---
title: "VMess"
description: "The VMess ciphers, transports, links and features Potatso supports."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.potatso.com/llms.txt
> Use this file to discover all available pages before exploring further.

# VMess

A VMess server is described by a **UUID**, a **cipher** that encrypts the traffic, and a **transport** that carries the connection, such as WebSocket or gRPC, with or without TLS. Potatso connects to a server when it supports the server's cipher, transport and TLS settings. Use the tables below to check your server's settings, as shown by your provider or in its `vmess://` link.

You can add a VMess server by hand, with a [`vmess://` link](#links), or by importing:

- a Clash or Mihomo subscription,
- an Xray or V2Ray configuration,
- a Surge configuration.

Potatso doesn't import VMess servers from a sing-box configuration yet. Use the server's `vmess://` link instead.

## Ciphers {#ciphers}

| Cipher | Supported |
| --- | --- |
| `auto` | ✅ Potatso picks `aes-128-gcm`, which every Apple device runs in hardware. |
| `aes-128-gcm` | ✅ |
| `chacha20-poly1305` | ✅ |
| `none` | ✅ |
| `zero` | ❌ |
| `aes-128-cfb` (legacy) | ❌ |

`none` and `zero` send your traffic unencrypted. Use `none` only with TLS, which then encrypts the connection. Potatso doesn't connect with `zero`, which also drops the protection against tampering: choose another cipher on your server.

### alterId {#alterid}

Potatso always uses the current VMess authentication, which is the same as `alterId` 0. Servers whose user still has an `alterId` above 0 accept it too, so you can leave the server as it is. Potatso doesn't support the old authentication that only `alterId` above 0 used, which servers have deprecated since 2022.

## Transports {#transports}

| Transport | Link `net` / `type` | Supported | Tested with |
| --- | --- | --- | --- |
| None (plain TCP) | `tcp`, or none | ✅ With or without TLS | Xray, sing-box, V2Ray |
| WebSocket | `ws` | ✅ With or without TLS and early data | Xray, sing-box, V2Ray |
| gRPC | `grpc` | ✅ With or without TLS | Xray, sing-box, V2Ray |
| HTTP/2 | `h2` or `http` | ✅ With TLS | sing-box, V2Ray |
| HTTP Upgrade | `httpupgrade` | ✅ With or without TLS | Xray, sing-box |
| TCP with an HTTP header | `tcp` with `type=http` | ❌ | |
| XHTTP | `xhttp` | ❌ | |
| mKCP, QUIC | `kcp`, `quic` | ❌ | |

Every supported transport works with UDP. Potatso doesn't import a server whose transport it doesn't support.

WebSocket early data sends the first bytes of a connection with the WebSocket handshake, saving a round trip. It's set by `?ed=2048` at the end of the link's path, or `max-early-data` in a Clash subscription.

Xray no longer offers HTTP/2: Xray servers that used it now use XHTTP, which Potatso doesn't support yet.

## TLS {#tls}

| Setting | Clash key | Link field | Supported |
| --- | --- | --- | --- |
| Server name (SNI) | `servername` | `sni` | ✅ Without one, Potatso uses the server's address. |
| ALPN | `alpn` | `alpn` | ✅ Without one, Potatso sends `http/1.1` for WebSocket and `h2` for gRPC and HTTP/2. |
| Skip certificate verification | `skip-cert-verify` | `allowInsecure` | ✅ |
| Browser fingerprint | `client-fingerprint` | `fp` | ✅ `chrome`, `firefox`, `safari`, `ios`, `android`, `edge` and `random`. Other names connect with a default handshake. |
| Certificate pinning | `fingerprint` | `pcs` | ❌ |
| REALITY | `reality-opts` | `security=reality` | ❌ |
| Encrypted Client Hello (ECH) | `ech-opts` | `ech` | ❌ |
| Custom CA certificate | | | ❌ |

Turning off certificate verification lets anyone between you and the server read your traffic. Potatso doesn't connect to a VMess server that needs REALITY, ECH or a certificate pin, because connecting without them wouldn't give the protection the server asks for. Use VLESS or Trojan for REALITY.

A browser fingerprint makes the connection's TLS handshake look like that browser's. It doesn't change what the server must support.

## UDP {#udp}

UDP is off by default for VMess servers. Turn on **UDP Relay** in the server's settings, or set `udp: true` in a Clash subscription.

Potatso sends each UDP flow over its own VMess connection, which every VMess server accepts. It doesn't support the XUDP and PacketAddr encodings (`packetEncoding` in a link, `packet-encoding` or `xudp` in a Clash subscription), which carry many UDP flows over one connection: a server set up with them still works, and Potatso tells you at import that it uses its own UDP instead. Apps that need full-cone NAT, such as some games, may not work with it.

With [multiplexing](#mux) on, UDP travels over the shared connection instead.

## Multiplexing {#mux}

Potatso can run several connections over one VMess connection, set with `smux` in a Clash subscription:

| Protocol | `smux` `protocol` | Servers |
| --- | --- | --- |
| Mux.Cool | `muxcool` | Xray, V2Ray and sing-box, with no server setting |
| sing-mux | `h2mux`, `smux`, `yamux` | sing-box with multiplexing turned on |

TCP and UDP both work. Mux.Cool closes both directions of a connection together, so an app that stops sending and then waits for the reply should use a server without multiplexing.

## Request options {#request-options}

A VMess client chooses a few options for each connection, and every server accepts any of them. Potatso always sends its traffic in encrypted chunks and marks the end of each upload, and it doesn't set the others:

| Option | Clash key | Potatso |
| --- | --- | --- |
| Chunk stream | | Always on |
| Chunk masking | | Off |
| Global padding | `global-padding` | Off. Potatso warns when you import a server that sets it. |
| Authenticated length | `authenticated-length` | Off. Potatso warns when you import a server that sets it. |

Chunk masking and global padding hide the size of each chunk from anyone watching. Without them, your traffic still can't be read, but its pattern is easier to recognise.

### Large uploads {#large-uploads}

A single VMess connection can upload about 1 GiB. VMess numbers its encrypted chunks with a counter that runs out after that, and continuing would weaken the encryption, so Potatso closes the connection instead. Downloads have no limit. For uploads larger than 1 GiB in one connection, use a VLESS or Trojan server.

## Feature support {#features}

| Feature | Supported |
| --- | --- |
| [AEAD authentication](https://www.v2fly.org/en_US/developer/protocols/vmess.html) (`alterId` 0) | ✅ |
| Legacy MD5 authentication (`alterId` above 0) | ❌ Servers with `alterId` above 0 accept the AEAD authentication. |
| Ciphers `aes-128-gcm`, `chacha20-poly1305`, `none`, `auto` | ✅ |
| Ciphers `zero` and the legacy `aes-128-cfb` | ❌ |
| Chunk stream, end-of-upload marker | ✅ |
| Chunk masking, global padding, authenticated length | ❌ Servers accept connections without them |
| UDP | ✅ One connection per flow |
| Uploads over about 1 GiB on one connection | ❌ See [Large uploads](#large-uploads) |
| XUDP, PacketAddr | ❌ |
| Mux.Cool | ✅ TCP and UDP |
| sing-mux (h2mux, smux, yamux) | ✅ TCP and UDP |
| Transports | See [Transports](#transports) |
| TLS | See [TLS](#tls) |
| [v2rayN share links](#links) (version 2) | ✅ |
| [Xray share links](https://github.com/XTLS/Xray-core/discussions/716) | ✅ |
| Shadowrocket share links | Import only |

## `vmess://` links {#links}

A `vmess://` link holds a whole server in one line. Potatso imports three forms and shares the first two.

The v2rayN form, the most common, is a Base64-encoded JSON object:

```text
vmess://base64({"v":"2","ps":"name","add":"host","port":"443","id":"uuid",…})
```

| Field | Description |
| --- | --- |
| `v` | Format version, `2`. |
| `ps` | Optional. The server's name in Potatso. |
| `add` | Server address. |
| `port` | Server port. |
| `id` | The UUID. |
| `aid` | `alterId`. See [alterId](#alterid). |
| `scy` | The [cipher](#ciphers). Without one, `auto`. |
| `net` | The [transport](#transports): `tcp`, `ws`, `grpc`, `h2` or `httpupgrade`. |
| `type` | `none`, or `http` for a TCP HTTP header, which Potatso doesn't support. |
| `host` | The `Host` header for WebSocket, HTTP/2 and HTTP Upgrade. |
| `path` | The path for WebSocket, HTTP/2 and HTTP Upgrade, or the service name for gRPC. A WebSocket path can end with `?ed=2048` for early data. |
| `tls` | `tls` to use TLS, or empty. |
| `sni`, `alpn`, `fp` | The [TLS](#tls) server name, ALPN list and browser fingerprint. |

The Xray form is a URL, with the cipher in `encryption` and the transport and TLS settings as query parameters:

```text
vmess://uuid@host:port?type=ws&security=tls&sni=…&host=…&path=…&encryption=auto#name
```

| Parameter | Description |
| --- | --- |
| `type` | The [transport](#transports). |
| `encryption` | The [cipher](#ciphers). Without one, `auto`. |
| `security` | `tls`, or `none`. |
| `sni`, `alpn`, `fp` | The [TLS](#tls) server name, ALPN list and browser fingerprint. |
| `host`, `path` | The `Host` header and path, as in the v2rayN form. |
| `serviceName` | The gRPC service name. |
| `ed` | WebSocket early data, in bytes. |

Potatso also imports Shadowrocket's form, `vmess://base64(cipher:uuid@host:port)?remarks=…&obfs=websocket&…`.

### Examples {#link-examples}

Each example shows the link to import. The UUID is `b831381d-6324-4d53-ad4f-8cda48b30811`.

WebSocket with TLS and early data, through `cdn.example.com`, with the Chrome fingerprint:

```text
vmess://eyJ2IjoiMiIsInBzIjoiV1MgVExTIiwiYWRkIjoidm1lc3MuZXhhbXBsZS5jb20iLCJwb3J0IjoiNDQzIiwiaWQiOiJiODMxMzgxZC02MzI0LTRkNTMtYWQ0Zi04Y2RhNDhiMzA4MTEiLCJhaWQiOiIwIiwic2N5IjoiYXV0byIsIm5ldCI6IndzIiwidHlwZSI6Im5vbmUiLCJob3N0IjoiY2RuLmV4YW1wbGUuY29tIiwicGF0aCI6Ii9yYXk/ZWQ9MjA0OCIsInRscyI6InRscyIsInNuaSI6ImNkbi5leGFtcGxlLmNvbSIsImFscG4iOiJodHRwLzEuMSIsImZwIjoiY2hyb21lIn0=
```

gRPC with TLS and `aes-128-gcm`, service name `vmess-grpc`:

```text
vmess://eyJ2IjoiMiIsInBzIjoiZ1JQQyIsImFkZCI6InZtZXNzLmV4YW1wbGUuY29tIiwicG9ydCI6IjQ0MyIsImlkIjoiYjgzMTM4MWQtNjMyNC00ZDUzLWFkNGYtOGNkYTQ4YjMwODExIiwiYWlkIjoiMCIsInNjeSI6ImFlcy0xMjgtZ2NtIiwibmV0IjoiZ3JwYyIsInBhdGgiOiJ2bWVzcy1ncnBjIiwidGxzIjoidGxzIiwic25pIjoidm1lc3MuZXhhbXBsZS5jb20ifQ==
```

Plain TCP with `chacha20-poly1305`, in the Xray form:

```text
vmess://b831381d-6324-4d53-ad4f-8cda48b30811@vmess.example.com:8080?type=tcp&encryption=chacha20-poly1305#Plain%20TCP
```

HTTP Upgrade with TLS, in the Xray form:

```text
vmess://b831381d-6324-4d53-ad4f-8cda48b30811@vmess.example.com:443?type=httpupgrade&security=tls&sni=cdn.example.com&host=cdn.example.com&path=%2Fupgrade&encryption=auto#HTTP%20Upgrade
```

### In a Clash subscription {#clash}

```yaml
proxies:
  - name: VMess WS
    type: vmess
    server: vmess.example.com
    port: 443
    uuid: b831381d-6324-4d53-ad4f-8cda48b30811
    alterId: 0
    cipher: auto
    udp: true
    tls: true
    servername: cdn.example.com
    network: ws
    ws-opts:
      path: /ray
      headers:
        Host: cdn.example.com
      max-early-data: 2048
      early-data-header-name: Sec-WebSocket-Protocol
```

Source: https://docs.potatso.com/protocols/vmess/index.mdx
