Skip to content

VMess — Xray-core

VMess is the classic AEAD-only V2Ray protocol. Xray-core supports only the AEAD variant — the legacy alterId-based MD5-AEAD mode has been removed. The runtime emits a deprecation notice on startup that recommends moving to VLESS encryption (infra/conf/vmess.go:67, 118).

Inbound

settings for an inbound of "protocol": "vmess":

FieldTypeDefaultAllowed valuesDescription
users[]json.RawMessage<user object array> | …Inbound account list; same object shape as `clients`. `users` is the newer name introduced in recent Xray and is accepted alongside `clients`.
clients[]json.RawMessage(required)<user object array>List of accepted users. Each entry holds the VMess account fields (id, security, experiments) plus the common user fields (email, level).
default*VMessDefaultConfig(unset)VMessDefaultConfigFallback user settings when an incoming connection does not match a configured client. Only the `level` field exists today.

Source: infra/conf/vmess.go:61-65 · pinned at v26.6.1 (94ffd50)

default

FieldTypeDefaultAllowed valuesDescription
levelbyte0<byte>Policy level applied to fallback users.

Source: infra/conf/vmess.go:50-52 · pinned at v26.6.1 (94ffd50)

clients[] — user object

Each clients[] entry is a VMessAccount plus the common user fields (email, level):

FieldTypeDefaultAllowed valuesDescription
idstring(required)<UUID>User UUID. Canonical 8-4-4-4-12 or dash-less hex. Parsed and re-canonicalized on load.
securitystringautoauto | aes-128-gcm | chacha20-poly1305 | none | zeroSymmetric cipher for the VMess payload. `auto` picks AES-GCM on x86 with AES-NI and ChaCha20 elsewhere. `zero` disables encryption (handshake-only).
experimentsstring(unset)<string>Comma-separated experiment flags forwarded into the protocol. Forwarded as `TestsEnabled` in the protobuf.

Source: infra/conf/vmess.go:18-22 · pinned at v26.6.1 (94ffd50)

Outbound

settings for an outbound of "protocol": "vmess":

FieldTypeDefaultAllowed valuesDescription
address*Address(unset)<host>Simplified shape — server hostname or IP. When set, `vnext` is constructed internally.
portuint16(required with address)<port>Server port (simplified shape).
leveluint320<uint32>User level (simplified shape).
emailstring(unset)<string>User identifier reported in stats.
idstring(required with address)<UUID>User UUID (simplified shape).
securitystringautoauto | aes-128-gcm | chacha20-poly1305 | none | zeroSame cipher set as inbound clients.
experimentsstring(unset)<string>Experiment flags forwarded to the server.
vnext[]*VMessOutboundTarget(use simplified shape)[{address,port,users:[user]}]Verbose shape — must hold exactly one server with exactly one user.

Source: infra/conf/vmess.go:115-124 · pinned at v26.6.1 (94ffd50)

Simplified vs. vnext

The outbound accepts either the simplified shape (address, port, id, security, ...) or the verbose vnext shape. The simplified form is rewritten into a single-entry vnext array (infra/conf/vmess.go:121-129). The verbose form must hold exactly one server with exactly one user — for multiple endpoints use multiple VMess outbounds and a routing balancer.

Examples

Minimal inbound:

json
{
  "inbounds": [
    {
      "tag": "vmess-in",
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vmess",
      "settings": {
        "clients": [
          { "id": "a3482e88-686a-4a58-8126-99c9df64b7bf", "email": "alice", "security": "auto" }
        ]
      },
      "streamSettings": { "network": "tcp", "security": "tls" }
    }
  ]
}

Simplified outbound:

json
{
  "outbounds": [
    {
      "tag": "vmess-out",
      "protocol": "vmess",
      "settings": {
        "address": "example.com",
        "port": 443,
        "id": "a3482e88-686a-4a58-8126-99c9df64b7bf",
        "security": "auto"
      },
      "streamSettings": { "network": "ws", "security": "tls", "wsSettings": { "path": "/vm" } }
    }
  ]
}

Notes

  • VMess in Xray is AEAD-only. There is no alterId field in the config struct. Configs migrated from V2Ray with "alterId": <n> should drop the field; the new client/server will reject the legacy MD5-AEAD mode anyway.
  • security: "auto" is the safe default: AES-GCM on platforms with AES-NI, ChaCha20-Poly1305 otherwise. Unknown security strings silently fall back to auto (infra/conf/vmess.go:37-38).
  • security: "zero" is for testing only — no symmetric encryption at all, the handshake is the only cryptographic protection.
  • A startup-time deprecation notice ("VMess (with no Forward Secrecy, etc.)") is printed whenever a VMess inbound or outbound is loaded (infra/conf/vmess.go:67, 118). VLESS with the new mlkem768x25519plus encryption is the recommended replacement.

Cross-core notes

  • sing-box uses users[].uuid instead of clients[].id, and exposes alter_id (snake_case), global_padding, and authenticated_length options that Xray no longer supports. See VMess — sing-box.
  • mihomo has a single proxy-object shape, uses the field name cipher for the security selector, and surfaces UDP-encoding switches (xudp, packet-addr, packet-encoding) on the outbound. See VMess — mihomo.

Source: infra/conf/vmess.go:18-124 · v26.6.1 (94ffd50)

Core Tutorial by Argsment