SagerNet / SagerNet/sing-box

VLESS REALITY: `reality verification failed` against Xray-core v26.9.8+ servers (server now requires X25519MLKEM768 key share)

Open
#4,520 3 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
38.2k
Forks
4.6k
Avg merge
19d 15h
Merged PRs (30d)
1

Description

Operating system

Linux

System version

Debian GNU/Linux 13 (amd64); also reproduced on Windows 11 x64 (client side is OS-independent)

Installation type

Original sing-box Command Line

If you are using a graphical client, please provide the version of the client.

No response

Version
sing-box version 1.12.25
Environment: go1.23.12 linux/mipsle

Also affected: 1.14.0 (go1.25.8 windows/amd64), 1.15.0-alpha.2, dev f6ce1d5 (metacubex/utls v1.8.7)
Description
What happened?

Since Xray-core v26.9.8 / v26.9.9 upgraded github.com/xtls/reality to v0.0.0-20260908062103-8cdf7bf9c7f0, every sing-box version I tested can no longer connect to REALITY servers running these builds. The client always fails with:

connection: open connection to <host>:443 using outbound/vless[out]: reality verification failed
Server-side root cause

REALITY commit 8cdf7bf9c7f0 ("REALITY protocol: Reject outdated/strange Client Hello that doesn't have X25519MLKEM768 before optional X25519") makes the REALITY server require the client ClientHello to contain an X25519MLKEM768 key share (listed before any plain X25519). If it is missing, the server treats the handshake as unauthorized and silently falls back to the configured destination, so the client-side session verification fails.

sing-box's chrome uTLS fingerprint (HelloChrome_Auto from metacubex/utls) does not emit an X25519MLKEM768 key share, so all sing-box REALITY handshakes are rejected by these servers.

Control experiments
  • The exact same client config against a server built from the same Xray-core v26.9.9 source but with github.com/xtls/reality pinned to the parent commit e1986a4d31ca (i.e. without this ClientHello check) connects fine (full-tunnel curl returns HTTP 204/200).
  • Current Xray-core clients (uTLS chrome) still connect to the v26.9.9 server without issues.

So the only variable is the server-side REALITY bump: sing-box's ClientHello is now classified as "outdated/strange" and rejected.

Suggested fix

Could sing-box, via metacubex/utls, emit an X25519MLKEM768-first key share for the chrome-family fingerprints (sync the Chrome fingerprint definitions from upstream refraction-networking/utls, or extend HelloChrome_Auto)? Otherwise all sing-box (and mihomo, same fork) REALITY users are locked out of servers running Xray-core >= v26.9.8 - the version server operators are now encouraged to run for the REALITY memory-leak fix.

Reproduction
Server (Xray-core v26.9.9, official release binary)

server.json:

{
  "inbounds": [
    {
      "tag": "reality",
      "listen": "127.0.0.1",
      "port": 8443,
      "protocol": "vless",
      "settings": {
        "clients": [{ "id": "48796f85-218b-42fb-88dd-55ac99d0a767", "flow": "xtls-rprx-vision" }],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "dest": "www.sonic.com:443",
          "serverNames": ["www.sonic.com"],
          "privateKey": "GNcg__Kp68P5txlaRHOQX-TYxlYS_fvsnWZ4W53g0Ek",
          "shortIds": ["87ed"]
        }
      }
    }
  ],
  "outbounds": [{ "protocol": "freedom" }]
}

Run: xray run -c server.json

Client (any affected sing-box build)

client.json:

{
  "inbounds": [{ "type": "mixed", "tag": "in", "listen": "127.0.0.1", "listen_port": 10808 }],
  "outbounds": [
    {
      "type": "vless",
      "tag": "out",
      "server": "127.0.0.1",
      "server_port": 8443,
      "uuid": "48796f85-218b-42fb-88dd-55ac99d0a767",
      "flow": "xtls-rprx-vision",
      "tls": {
        "enabled": true,
        "server_name": "www.sonic.com",
        "utls": { "enabled": true, "fingerprint": "chrome" },
        "reality": { "enabled": true, "public_key": "ywFgsEouyJvRVRxWvkhes19RSblBm6y0p6NT5IHSFD8", "short_id": "87ed" }
      }
    }
  ]
}

Run: sing-box run -c client.json, then curl --socks5 127.0.0.1:10808 https://www.gstatic.com/generate_204 -> fails; the sing-box log shows reality verification failed.

Clients tested (all fail)
  • 1.12.25 (go1.23.12, linux/mipsle)
  • 1.14.0 (go1.25.8, windows/amd64)
  • 1.15.0-alpha.2
  • dev f6ce1d5 (metacubex/utls v1.8.7), with fingerprints chrome, chrome_pq, chrome_pq_psk
Control experiment

Rebuild the server from the same v26.9.9 source tree with only github.com/xtls/reality pinned to the parent commit (go get github.com/xtls/reality@v0.0.0-20260908045812-e1986a4d31ca, commit e1986a4d31ca, i.e. without the ClientHello check). The exact same configs then work and curl returns 204.

Logs
dev f6ce1d5, fingerprint chrome:


ERROR [...] connection: open connection to www.gstatic.com:443 using outbound/vless[out]: reality verification failed


1.12.25 / 1.14.0 / 1.15.0-alpha.2 show the same `reality verification failed` error.
Supporter
Integrity requirements
  • I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
  • I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
  • I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
  • I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproducible server.json and client.json configurations and the chrome/HelloChrome_Auto fingerprint behavior described in the issue. Compare the affected fingerprint definitions with upstream uTLS and verify against Xray-core v26.9.9; done means the supplied curl request succeeds and the client no longer reports reality verification failed.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
networking, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.