Skip to content

REALITY fails with www.microsoft.com target when Certificate TLS record is 8273 bytes (>8192 hardcoded limit) #6356

Description

@fanyangCS

Integrity requirements

  • I have read all the comments in the issue template and ensured that this issue meets the requirements.
  • I confirm that I have read the documentation and understand the relevant configuration items.
  • I provide a minimal, sanitized reproduction and logs; secrets such as UUID, private key, public key, and shortId are redacted.
  • I searched existing issues and did not find an exact duplicate for this server-side REALITY target Certificate record size failure.
  • The problem can be reproduced on the latest release.

Description

VLESS + TCP + REALITY + Vision fails when using www.microsoft.com:443 as REALITY dest / serverNames on Xray-core v26.3.27.

This is not a direct TLS rejection by Microsoft: direct openssl s_client and curl from the same server to www.microsoft.com:443 succeed. The failure appears to be caused by the REALITY server-side target handshake parser rejecting a Microsoft TLS Certificate record whose length is slightly larger than the hardcoded 8192 byte limit in github.com/xtls/reality.

In this environment, Microsoft returns a TLS Certificate record length that leads REALITY to log Certificate: 8273, which is larger than size = 8192, and then the REALITY connection is rejected with handshake did not complete successfully.

Environment

  • Xray-core: Xray 26.3.27 (Xray, Penetrates Everything.) d2758a0 (go1.26.1 linux/amd64)
  • OS: Linux x86_64
  • Protocol: VLESS + TCP + REALITY + xtls-rprx-vision
  • REALITY dest/serverName: www.microsoft.com:443 / www.microsoft.com
  • Client REALITY fingerprint: chrome

Sanitized server config shape

{
  "log": { "loglevel": "debug" },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "<redacted-uuid>",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": true,
          "dest": "www.microsoft.com:443",
          "xver": 0,
          "serverNames": ["www.microsoft.com"],
          "privateKey": "<redacted>",
          "shortIds": ["<redacted>"]
        }
      }
    }
  ],
  "outbounds": [{ "protocol": "freedom", "tag": "direct" }]
}

Client uses matching VLESS REALITY settings with:

security=reality
sni=www.microsoft.com
fp=chrome
flow=xtls-rprx-vision
type=tcp

Reproduction

  1. Start Xray server with REALITY dest: "www.microsoft.com:443", serverNames: ["www.microsoft.com"], show: true.
  2. Use a matching Xray client on the same host or from another host.
  3. Send a request through the client, for example:
curl --socks5-hostname 127.0.0.1:<local-socks-port> https://www.google.com/generate_204

Observed client-side result:

curl: (35) Recv failure: Connection reset by peer
HTTP=000 ERR=Recv failure: Connection reset by peer

REALITY debug log

Relevant sanitized server-side REALITY logs:

REALITY remoteAddr: 127.0.0.1:<port>
REALITY remoteAddr: 127.0.0.1:<port> hs.c.ClientVer: [26 3 27]
REALITY remoteAddr: 127.0.0.1:<port> hs.c.ClientTime: 2026-06-21 ... UTC
REALITY remoteAddr: 127.0.0.1:<port> hs.c.ClientShortId: [<redacted>]
REALITY remoteAddr: 127.0.0.1:<port> hs.c.conn == conn: true
REALITY remoteAddr: 127.0.0.1:<port> len(s2cSaved): 5524 Server Hello: 127
REALITY remoteAddr: 127.0.0.1:<port> len(s2cSaved): 5397 Change Cipher Spec: 6
REALITY remoteAddr: 127.0.0.1:<port> len(s2cSaved): 5391 Encrypted Extensions: 51
REALITY remoteAddr: 127.0.0.1:<port> len(s2cSaved): 5340 Certificate: 8273
REALITY remoteAddr: 127.0.0.1:<port> hs.c.isHandshakeComplete.Load(): false
transport/internet/tcp: REALITY: processed invalid connection from 127.0.0.1:<port>: handshake did not complete successfully

Direct TLS to Microsoft succeeds

From the same server, direct TLS to Microsoft succeeds:

openssl s_client -connect www.microsoft.com:443 -servername www.microsoft.com -tls1_3 -brief </dev/null

Output excerpt:

CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: C = US, ST = WA, L = Redmond, O = Microsoft Corporation, CN = www.microsoft.com
Verification: OK
DONE

curl https://www.microsoft.com/ also returns HTTP 200 from the same server.

Microsoft Certificate record size

With openssl -msg, Microsoft returns a Certificate record that can exceed the REALITY hardcoded size limit when OCSP/status is involved:

openssl s_client -connect www.microsoft.com:443 -servername www.microsoft.com -tls1_3 -status -msg </dev/null

Relevant output:

<<< TLS 1.2, RecordHeader [length 0005]
    17 03 03 20 4c
<<< TLS 1.3, Handshake [length 203b], Certificate

0x204c + 5 = 8273, matching the REALITY debug log line:

Certificate: 8273

Suspected root cause

In github.com/xtls/reality tls.go, the current code appears to have a hardcoded 8192 byte limit:

var (
    size = 8192
    ...
)
...
handshakeLen = recordHeaderLen + Value(s2cSaved[3:5]...)
...
if handshakeLen > size { // too long
    break f
}

For this Microsoft target, REALITY computes:

handshakeLen = 8273
size = 8192
8273 > 8192

So the target TLS handshake is rejected as too long, and the connection fails with:

handshake did not complete successfully

Control test

Using the same UUID/key/flow/shortId/client, changing only the REALITY target to another site succeeds. For example:

  • www.bing.com:443 + serverNames: ["www.bing.com"] succeeds.
  • Other tested targets such as Cloudflare/Apple/Amazon also succeeded in the same environment.

This suggests the failure is target-handshake-size dependent rather than a UUID/key/shortId/flow mismatch.

Expected behavior

REALITY should either:

  1. handle valid target TLS Certificate records slightly larger than 8192 bytes, or
  2. expose a clearer error such as target TLS record too long: 8273 > 8192, or
  3. document that target TLS records must be <= 8192 bytes and that large OCSP-stapled certificate records are unsupported.

Actual behavior

The connection is reset and server logs only:

handshake did not complete successfully

This makes it look like a generic REALITY handshake/authentication failure, even though the specific cause appears to be the target Certificate record exceeding the hardcoded 8192 byte limit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions