Xray XHTTP Transport: Setup and XHTTP vs HTTP (2026)
What XHTTP in Xray is, how it differs from HTTP, WS and gRPC, and how to configure it on server and client for better DPI resistance. With examples.
Content of the article
- Introduction
- Basics
- Deep dive
- Practical section 1: minimal vless+xhttp over tls setup
- Practical section 2: xhttp behind a reverse proxy (nginx/caddy)
- Practical section 3: xhttp with cdn/edge
- Practical section 4: dpi resilience and masking
- Practical section 5: observability, testing, metrics
- Practical section 6: step-by-step connection debugging
- Practical section 7: performance and tuning
- Common mistakes
- Tools and resources
- Cases and results
- Faq
- Conclusion
Introduction
XHTTP transport for Xray has rapidly become one of the most practical ways to disguise traffic as regular HTTP and keep connections stable from 2024 through 2026. The reason is simple: many networks continue to allow classic HTTP(S) for legitimate traffic, and XHTTP emulates this dialogue without heavy HTTP/2 or WebSocket framing. In this guide, we'll explore what XHTTP means in the context of Xray, how it works under the hood, how it differs from standard HTTP transport, provide robust DPI-resistant configuration schemes, checklists, tips for performance and observability, as well as common pitfalls that break connections in real networks. In the end, you'll have a systematic methodology to design, deploy, and maintain XHTTP tailored to your scenarios — from home access to corporate perimeter and mobile networks.
Basics
What are Xray and transport?
Xray-core is a high-performance proxy engine offering a flexible model of protocol + transport + encryption. Application-level protocols (VLESS, VMess, Trojan, etc.) handle authentication and session multiplexing, while transport (TCP, WebSocket, HTTP/2, gRPC, QUIC, XHTTP) defines how bytes flow over the network and which network signatures DPI and intermediaries can see. Encryption (TLS/XTLS/REALITY) and client imitation (uTLS, JA3 fingerprints) hide contents and mask the TLS profile to behave like real browsers.
Where does XHTTP fit in this matrix?
XHTTP is a transport mode that mimics the behavior of classic HTTP/1.1 dialogue and supports both TLS and plain TCP (no need for h2c equivalents). Its goal is to present the most "ordinary" DPI profile possible: headers, methods, paths, keep-alive, chunked transfer encoding, Upgrade patterns — then after a legitimate handshake, shift the stream into a bidirectional byte channel for real proxy traffic. From the outside, it looks like a long-lived HTTP request/response with a live connection; internally, it acts as a pipeline for your VLESS/VMess data.
Why does it work against DPI?
- HTTP/1.1 semantics. Most DPI systems "understand" and permit typical HTTP headers, methods (GET/POST/OPTIONS), encodings (chunked), and keep-alive connections.
- Minimal framing. Unlike HTTP/2 and WebSocket, XHTTP doesn’t introduce explicit frames/opcodes, keeping the stream as if it’s a POST body or a connection upgrade. For many inspectors, this is a "normal" pattern.
- Flexible mimicry. Headers (User-Agent, Accept, Referer), paths, hosts, response codes, and even transmission intervals can be tailored to real backend behaviors.
What to compare it with: standard HTTP transport in Xray
Xray provides an HTTP transport (often HTTP/2 or h2c-like modes) oriented around framing and multiplexing streams inside HTTP/2. This approach is convenient but leaves obvious fingerprints (ALPN h2, HPACK profiles, specific prefaces) and requires more complex negotiation. XHTTP avoids clear HTTP/2 signals and is often preferable in "restricted" networks that allow only "simple" HTTP/1.1 over TLS 1.3, while HTTP/2/H3 segments are suspected or blocked.
Deep Dive
XHTTP Stream Architecture
- TLS/TCP establishment. The client establishes a TCP (or TLS) connection. When TLS is used, uTLS is enabled to mimic a real browser (JA3, SNI, ALPN — usually http/1.1 plus optionally h2 for plausibility).
- HTTP request. The client sends a plausible HTTP/1.1 request: a method (often POST or GET), a path (e.g., /api, /health, /v1/upload), headers (Host, User-Agent, Accept, Accept-Language, Content-Type, Connection: keep-alive, TE: trailers, Cache-Control, X-Requested-With, etc.). Two patterns are possible: a "long POST body" or an "Upgrade-like" exchange.
- Server response. The server replies with 200/204/101 (depending on the pattern), proper server headers (Server: nginx, Date, Content-Type, Transfer-Encoding: chunked, Connection: keep-alive), and then keeps the connection open.
- Tunnel. After that, both sides start exchanging the "useful" Xray protocol bytes hidden within the body/chunked segments. To the DPI, this is a live HTTP connection with a continuing body/chunks.
Key differences between XHTTP, HTTP/2, and WebSocket
- No explicit browser-level framing. H2/H3 are detectable via ALPN h2/h3, priorities, HPACK/QPACK. WS reveals Upgrade: websocket, Sec-WebSocket-Key/Accept headers. XHTTP uses "regular" headers.
- Fewer signatures. DPI is often trained to detect WebSocket and unusual HPACK profiles. XHTTP fits into the old, well-known HTTP/1.1 stack.
- Flexible false targets. It can convincingly imitate a downloader, uploader, long SSE, or slow API endpoint.
- Reliability in "noisy" networks. Simple HTTP/1.1 and chunked handling often work reliably behind corporate proxies and NATs.
Performance and overhead
- Header overhead: small but predictable; negligible impact over long sessions.
- RTT: one extra RTT for HTTP request/response beyond TLS handshake, reduced by keep-alive and early data (if supported).
- Throughput: comparable to plain TCP+TLS; bottlenecks are proxy/load balancer and buffering.
Compatibility and ALPN
In practice, ALPN set to "http/1.1" provides the most neutral profile. If the network prefers h2, you can add "h2" to the list, but the server must handle it correctly; otherwise, negotiation causes extra failures. For more realism, enable uTLS emulating recent Chrome/Firefox.
Practical Section 1: Minimal VLESS+XHTTP over TLS setup
Goal
Set up Xray with the VLESS protocol and XHTTP transport on 443/tcp with a valid certificate. Externally, host a regular website on the same domain or a static placeholder; proxy traffic goes through the XHTTP path.
Steps
- Domain and DNS. Configure A/AAAA records pointing to your VPS. Make sure your IP isn’t on obvious blocklists.
- Certificate. Install certbot or Caddy for automatic TLS. Minimize unnecessary ALPNs if you’re not using h2.
- Xray. Update to the current 2026 version. Confirm that your build supports the XHTTP transport.
- Server configuration. Create an inbound VLESS with streamSettings: network: xhttp, security: tls. Set up plausible headers and path.
- Client configuration. Use the same network: xhttp, serverName, and path/host as the server. Enable uTLS.
- Firewall. Allow 443/tcp and block unnecessary ports. Enable conntrack optimizations.
- Verification. Run curl -v https://your_domain/path — you should get a genuine 200/204. Then check client connection and metrics in logs.
Example parameters (abridged)
Server: protocol: vless; clients: UUID; decryption: none; streamSettings: network: xhttp; security: tls; tlsSettings: serverName: your_domain; alpn: ["http/1.1"]; xhttpSettings: host: ["your_domain"], path: "/api", method: "POST", headers: {"User-Agent": ["Mozilla/5.0"], "Accept": ["*/*"], "Connection": ["keep-alive"]}, idle_timeout: 60–120s.
Client: server: your_domain; port: 443; protocol: vless; uuid: same; tls: enabled; utls: chrome; alpn: ["http/1.1"]; xhttpSettings: same host/path/method/headers.
Resilience checklist
- ALPN only includes "http/1.1" if the network is suspicious of h2/h3.
- Headers and method appear as a legitimate API call.
- Path exists on the site and returns 200/204 without redirects.
- Server responds properly with Date, Server, and Connection headers.
- Keep-Alive is enabled, and idle_timeout isn’t too short.
Practical Section 2: XHTTP behind a reverse proxy (Nginx/Caddy)
When to use it
If your domain already hosts a site/application, it’s handy to hide XHTTP behind a reverse proxy routing by path or host. This adds plausibility and offloads TLS/HTTP details to a familiar web server.
Setup
- The web server (443/tls) accepts all incoming traffic.
- Regular traffic is served by the application/static files.
- Requests to /api (or a hidden path) are proxied to 127.0.0.1:Xray port.
- Xray listens on a local port (e.g., 127.0.0.1:18085) without its own TLS, using network: xhttp in cleartext because external TLS is handled by Nginx/Caddy.
Best practices
- In Nginx, ensure proxy_request_buffering is off for the XHTTP path to preserve interactivity.
- Set headers typical for your site so the server response looks organic: Server, Content-Type, Cache-Control.
- Watch proxy_read_timeout and keepalive_requests values—they should allow long-lived connections.
Checklist
- The site reliably returns 200/204 at the XHTTP path when tested with curl.
- Redirects (301/302) and error codes (401/403) are excluded for the XHTTP path.
- Header and body sizes stay within web server limits.
Practical Section 3: XHTTP with CDN/edge
CDN risks
Some CDNs aggressively buffer or rewrite headers; long-lived POSTs may be limited. If you need to mask behind a CDN, test end-to-end behavior: support for chunked encoding, no forced connection closure due to inactivity, and preservation of Connection: keep-alive.
Recommendations
- Use a "shallow" path and realistic POST method with a small Content-Length at start followed by chunked data.
- Scale read/write timeouts on both edge and origin sides.
- Limit non-standard headers; avoid exotic header names.
- Check whether the CDN adds headers affecting the signature.
Practical Section 4: DPI resilience and masking
uTLS and TLS fingerprints
Enable imitation of a recent browser (Chrome, Firefox). This includes plausible cipher suites, extensions order, ALPN keys, and GREASE. Keep updated since browser fingerprints evolve quarterly.
HTTP profile
- Method: POST is realistic for uploads and long-polling. GET with Transfer-Encoding: chunked is possible but less common.
- Headers: User-Agent matching your OS’s real browser. Accept, Accept-Language, Accept-Encoding align with UA. Avoid conflicting header pairs.
- Responses: 200/204 with correct Date, Content-Type, Server headers. For Upgrade pattern — 101 Switching Protocols with realistic fields.
- Intervals: transmission jitter imitates app behavior. Avoid strictly uniform batches every N milliseconds.
Ports and routing
- 443/tcp is the natural choice. Ports like 8443, 444, 7443 are possible but less plausible.
- IPv6 is often less noisy; use dual-stack if supported by the network.
- Split domains: main content on apex; XHTTP on a subdomain with shared branding.
Alternatives and complementary techniques
- REALITY: masks TLS as a real site without needing a certificate for the target domain. A solid fallback layer.
- gRPC: mimics corporate API noise but leaves detectable signatures.
- WebSocket: compatible with many load balancers but has a distinct Upgrade pattern.
Practical Section 5: Observability, testing, metrics
Connection checks
- curl -v https://domain/path — confirm expected status codes and headers.
- tcpdump/wireshark: verify ALPN, SNI, packet sizes, and timing intervals.
- Xray logs: look for successful handshakes, no early closes, or timeouts.
Load testing
- Vary RTT and loss (using tc netem) and monitor stream recovery.
- Measure P95/P99 latency for short tunnelled requests.
- Compare throughput of XHTTP against WS/H2 on your infrastructure.
Signs of degradation
- Unexpected 301/302 redirects on the XHTTP path.
- Connections closed prematurely by CDN/reverse proxy before your timeouts.
- High share of TCP RST packets from middleboxes.
Practical Section 6: Step-by-step connection debugging
- Certificate: check the chain and validity dates.
- ALPN: ensure it fixes on "http/1.1". If h2 is needed, verify the server supports h2 for XHTTP.
- Route: traceroute from client to IP. If asymmetry or black holes appear, change route/provider.
- Reverse proxy: disable buffering, verify timeouts.
- Site placeholder: path returns an honest response with proper headers.
- uTLS: switch browser profile, verify JA3 fingerprint.
- Exclude CDN: test direct to origin first, then re-enable CDN.
Practical Section 7: Performance and tuning
- MTU/MSS: set optimal values on VPS to avoid fragmentation in mobile networks. TCP MSS clamping to 1360–1400 bytes often helps in TLS tunnel scenarios.
- Buffer sizing: disable extra buffering for the XHTTP path in Nginx/Caddy. Increase recv/send buffers in Xray for high RTT links.
- Idle timeouts: 60–120 seconds for noisy networks; 300+ seconds for stable channels.
- Header realism: imitate the header sets and order typically used by your stack’s websites.
Common mistakes
- Mismatched host/path between client and server — handshake succeeds but no data flows.
- ALPN conflict: client requests h2 but server doesn’t support it — causing extra RSTs or ERR_HTTP2_INADEQUATE.
- Reverse proxy buffering: long-poll connections break due to proxy_request_buffering being on.
- Suspicious headers: mismatched Accept-Encoding and User-Agent.
- Empty site response with 404/405 on XHTTP path — DPI flags this as an anomaly.
- Excessive non-standard X-* headers. They’re unnecessary and increase profile entropy.
Tools and resources
What to use in 2026
- Latest Xray-core with XHTTP and uTLS support.
- Reverse proxy: Nginx, Caddy. Caddy simplifies automatic TLS and HTTP/1.1 behavior out of the box.
- Network profile analysis: ja3/s_jA3 for TLS, h2spec/h2c tests when needed, tcpdump/wireshark for pcap captures.
- Load testing: vegeta, wrk to simulate background HTTP, iperf3 over the tunnel for bandwidth measurements.
- Monitoring: Xray metrics (if enabled), system metrics (conntrack, sockets), reverse proxy logs.
Infrastructure alternative
vpn.how provides personal VPN servers with dedicated IP addresses. Available locations, protocols and current prices are shown on the website and in your account. Payment methods and the final amount are displayed at checkout. Choose a server
Cases and results
Case 1: Campus network with aggressive DPI
Conditions: only HTTPS on 443 allowed, HTTP/2 often unstable, WebSocket occasionally breaks. Solution: VLESS+XHTTP on 443 with ALPN=http/1.1, path /api/metrics, POST+chunked, reverse proxy Caddy. Result: connection success 98–99% (previously 70–80% on WS), median latency +8–12 ms over TLS baseline, throughput 70–85% of plain TCP by iperf3 — acceptable for applications.
Case 2: Corporate perimeter with proxy
Conditions: transparent proxies rewriting headers and buffering bodies. Solution: XHTTP behind Nginx with proxy_request_buffering off, keepalive_requests=1000, correct server headers. Result: long-lived session drops disappeared, connections held for over 2 hours without forced idle close.
Case 3: Mobile operator blocking QUIC and h2
Conditions: h3 blocked, h2 degraded, 443/tcp "clean." Solution: XHTTP with uTLS Chrome profile, port 443, realistic UA and Accept-Language, MSS clamp 1380. Result: stable 10–30 Mbps, no RST spikes under load, successful access to previously DPI-blocked services.
FAQ
1. Why is XHTTP better than WebSocket in Xray?
WS reveals itself via Upgrade: websocket and Sec-WebSocket-* headers. DPI often recognizes these signatures. XHTTP uses regular HTTP/1.1 dialogue with no WS-specific fields, reducing classification risk. Its overhead is smaller or comparable.
2. How does XHTTP differ from standard HTTP transport (HTTP/2) in Xray?
HTTP/2 enables multiplexing at frame level and a distinctive profile (ALPN h2, priorities, HPACK). XHTTP is a simple HTTP/1.1 imitation where the useful stream travels as body/chunks without explicit h2 framing. This makes it less noticeable and often more resilient.
3. Can XHTTP be used without TLS?
Technically yes (cleartext), especially behind a reverse proxy on localhost. On the Internet, it’s not recommended: TLS hides contents and lowers classification risk. Without TLS, DPI can see all requests and responses.
4. Is XHTTP compatible with CDNs?
Depends on the CDN and its settings. Proper support for chunked encoding, no aggressive buffering, and no idle timeouts are necessary. Always test end-to-end at your target CDN PoP.
5. Which protocol to choose over XHTTP — VLESS, VMess, or Trojan?
VLESS is considered "clean" and flexible for modern scenarios; VMess is historically widespread; Trojan is simple. For DPI, the external profile (TLS/uTLS+XHTTP) and HTTP behavior matter more than inner protocol semantics.
6. What about ECH/REALITY and XHTTP?
ECH encrypts ClientHello and removes SNI but has patchy server/client support. REALITY is another masking method working well as a fallback. XHTTP coexists with them but often uTLS+TLS1.3+XHTTP is enough.
7. Why do I sometimes see 301/302 redirects on the XHTTP path?
Automatic redirects from the site/app (e.g., to https or another host) affect the XHTTP path. Create a dedicated location without redirects or auth/CSRF logic.
8. How to configure timeouts?
Reverse proxy: set proxy_read_timeout between 90s and 600s depending on the profile. In Xray, idle_timeout 60–300 seconds. Ensure upstream layers (CDN/proxy) don't close connections before Xray does.
9. How to test header realism?
Capture real browser traffic to your site, collect frequent headers and their order. Compare with what your XHTTP client sends, remove exotic headers, and pick a believable User-Agent/Accept/Language set.
10. Can multiple logical streams be multiplexed in XHTTP?
Yes, this is done by the upper-level protocol (e.g., VLESS/VMess via Mux). But measure latency carefully: with high RTT, many substreams in one HTTP channel degrade tail latency.
Conclusion
XHTTP transport for Xray is a practical tool that "speaks" the familiar HTTP/1.1 language for the network and minimizes DPI-visible signatures. Its strength lies in simplicity: believable headers, proper keep-alive semantics, and no explicit WebSocket or HTTP/2 signs. Combined with TLS 1.3 and uTLS, it provides stable connections where WS/H2/H3 raise suspicion, while reverse proxy lets you organically embed the tunnel into an operational website. Start with a minimal VLESS+XHTTP scheme on 443 with uTLS, then add a reverse proxy without buffering, tune timeouts, and verify CDN behavior — you'll get a reliable channel. Keep observability, realistic headers, and uTLS profile updates in mind. If a backup or personal IP is needed, evaluate infrastructure alternatives. Next, automate deployments, keep a couple of domains for rotating scenarios, and review masking parameters quarterly against new DPI patterns. That way, XHTTP will be a manageable part of your network architecture, not just a one-time trick.
Publisher: vpn.how