--- title: REALITY description: Set up a VLESS + REALITY inbound with XTLS-Vision in 3x-ui — keys, short IDs, SNI, fingerprints, and common pitfalls. icon: ShieldCheck --- **REALITY** is an Xray transport security that disguises your proxy as ordinary traffic to a real, popular website. Unlike classic TLS, your server needs **no certificate of its own** — it borrows the TLS handshake of the target site (`dest`). Combined with the **XTLS-Vision** flow, it is fast and resistant to deep-packet inspection. REALITY is used with **VLESS** (and Trojan). The recommended flow is `xtls-rprx-vision`. ## Key settings When you choose **REALITY** as the security mode on a VLESS inbound, 3x-ui exposes these fields: | Field | What it is | | ------------------------ | ------------------------------------------------------------------ | | **Dest (target)** | A real TLS site to impersonate, e.g. `www.microsoft.com:443`. | | **SNI / Server Names** | The hostname(s) clients send; must match the target's certificate. | | **Public / Private key** | An **x25519** keypair. The private key stays on the server. | | **Short IDs** | Hex strings used to authenticate clients (you can have several). | | **Flow** | Set to `xtls-rprx-vision`. | | **Fingerprint (uTLS)** | The client TLS fingerprint to mimic, e.g. `chrome`. | The private key is generated with Xray's `x25519` utility (the panel can generate the pair for you): ```bash title="generate an x25519 keypair" xray x25519 ``` ## Set it up in the panel ### Create a VLESS inbound Add a new inbound, choose protocol **VLESS**, and set **Security** to **reality**. ### Choose a target (dest) and SNI Pick a reputable site that supports TLS 1.3 and HTTP/2 and is reachable from your server and your clients (for example `www.microsoft.com:443`). Set the server names / SNI to match that site's certificate. ### Generate keys and short IDs Generate the x25519 keypair and one or more short IDs. Keep the **private key** secret; clients only ever receive the **public key**. ### Set the flow and fingerprint Use the `xtls-rprx-vision` flow and a common uTLS fingerprint such as `chrome`. ### Add a client and share the link Create a client, then use its share link or QR code in a compatible app (v2rayNG, Hiddify, Mihomo, and others). ## What the configuration looks like On the server, a REALITY inbound's `streamSettings` looks roughly like this: ```json title="server inbound (excerpt)" { "network": "tcp", "security": "reality", "realitySettings": { "dest": "www.microsoft.com:443", "serverNames": ["www.microsoft.com"], "privateKey": "", "shortIds": [""], "fingerprint": "chrome" } } ``` The matching client share link carries the **public** parameters: ```text title="vless:// (excerpt)" vless://@:443?security=reality&pbk=&sid=&sni=www.microsoft.com&fp=chrome&spx=%2F&flow=xtls-rprx-vision#my-reality ``` - `pbk` — REALITY **public** key - `sid` — short ID (matches one on the server) - `sni` — server name (matches the target's certificate) - `fp` — client fingerprint - `spx` — spiderX path - `flow` — `xtls-rprx-vision` ## Common pitfalls - **Bad target.** The `dest` must be a real site that supports **TLS 1.3** and **HTTP/2**, is reachable, and isn't blocked in your region. Pick a site you do not own and that sees lots of traffic. - **SNI mismatch.** The SNI / server names must match the target's real certificate, or the handshake gives the disguise away. - **Leaked private key.** Only ever distribute the **public** key to clients. - **Wrong flow.** REALITY + XTLS-Vision needs `flow = xtls-rprx-vision` on both the inbound client entry and the share link. - **Client version limits.** Xray-core v26.9.8+ no longer sets a minimum when **Min Client Ver** is empty. An explicitly saved minimum still applies. Earlier builds may use a built-in minimum (such as `26.3.27`), rejecting third-party clients even with correct keys. Check the running core version before changing this gate; lowering it also admits older fingerprints. - **Mihomo and ML-KEM.** Xray-core v26.9.8+ independently requires an `X25519MLKEM768` key share before the optional `X25519` share. The Clash/Mihomo YAML subscription enables `reality-opts.support-x25519mlkem768` for REALITY nodes, including external links, and uses `chrome` when no fingerprint was set. Explicit fingerprints are preserved: choose one that offers ML-KEM (`chrome` with Mihomo's uTLS v1.8.7); enabling the flag cannot upgrade an old fingerprint. Raw `vless://` links carry the equivalent `support-x25519mlkem768=true` hint; clients that support this URI extension, including current Mihomo builds, apply it on import. Servers on Xray-core older than 26.9.8 accept a plain `X25519` hello, and very old ones reject ML-KEM outright. For those, or where a network drops the larger ML-KEM ClientHello, enable **Mihomo X25519** on a Host: its Clash proxy gets `support-x25519mlkem768: false` and its `vless://` link drops the hint. Clearing the version limit alone does not fix the handshake. ## Generate a config Use the generator below to create a fresh X25519 keypair, UUID, and short ID, then copy the server inbound JSON and the client share link. Everything is computed **in your browser** — no keys or links are sent anywhere. The **private key** belongs only on your server. Share the generated `vless://` link (which contains the **public** key) with clients.