Skip to content

Hysteria2 inbound: UDP traffic is never written to the access log #6574

Description

@Mishmix

Summary

The Hysteria2 inbound never writes UDP entries to the access log. TCP entries are written normally. VLESS inbounds in the same instance log both TCP and UDP.

This makes UDP traffic through a Hysteria2 inbound effectively invisible: there is no way to tell which user sent UDP, where it went, or whether it was dispatched at all.

Version

Reproduced on both:

  • Xray 26.3.27 (d2758a0)
  • Xray 26.7.28 (5ca6f4b)

Config

{
  "log": { "access": "/cfg/access.log", "loglevel": "warning" },
  "stats": {},
  "policy": {
    "levels": { "0": { "statsUserUplink": true, "statsUserDownlink": true } },
    "system": { "statsInboundUplink": true, "statsInboundDownlink": true }
  },
  "inbounds": [{
    "tag": "HY-TEST",
    "listen": "127.0.0.1",
    "port": 2099,
    "protocol": "hysteria",
    "settings": { "version": 2, "clients": [{ "auth": "secret123", "email": "tester42" }] },
    "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
    "streamSettings": {
      "network": "hysteria",
      "security": "tls",
      "tlsSettings": {
        "alpn": ["h3"],
        "certificates": [{ "certificateFile": "/cfg/c.pem", "keyFile": "/cfg/k.pem" }]
      },
      "hysteriaSettings": { "version": 2 }
    }
  }],
  "outbounds": [{ "tag": "direct", "protocol": "freedom" }]
}

Steps to reproduce

Official hysteria client with both a SOCKS5 listener and a UDP forwarder:

server: 127.0.0.1:2099
auth: secret123
tls:
  sni: test.local
  insecure: true
socks5:
  listen: 127.0.0.1:10999
udpForwarding:
  - listen: 127.0.0.1:15999
    remote: 8.8.8.8:53
    timeout: 10s

Then generate one TCP flow and two UDP flows:

curl --socks5-hostname 127.0.0.1:10999 https://api.ipify.org
dig @127.0.0.1 -p 15999 example.com +short
dig @127.0.0.1 -p 15999 github.com +short

Both dig calls return correct answers, so the UDP relay itself works.

Actual access log

2026/08/01 16:50:11.340278 from 127.0.0.1:46365 accepted tcp:api.hy2.io:443 [HY-TEST >> direct] email: tester42
2026/08/01 16:50:16.311408 from 127.0.0.1:46365 accepted tcp:api.ipify.org:443 [HY-TEST >> direct] email: tester42

Two TCP lines. Zero UDP lines, despite two successful UDP round trips.

Expected

A line per UDP session, the way a VLESS inbound produces them:

... accepted udp:8.8.8.8:53 [VLESS-IN -> direct] email: someone

Additional detail

At "loglevel": "info" the UDP flow does appear in the error log, but without the inbound tag and without the user:

[Info] [4011292065] app/dispatcher: default route for udp:8.8.8.8:53
[Info] [4011292065] proxy/freedom: connection opened to udp:8.8.8.8:53, local endpoint [::]:38973, remote endpoint 8.8.8.8:53

For TCP there is a corresponding proxy/hysteria: tunnelling request to tcp:... line; for UDP there is no proxy/hysteria line at all, which suggests the UDP path bypasses the code that emits the access message.

Because no line in the info log ties that connection id to a user or an inbound, the UDP flow cannot be attributed even with verbose logging on.

Impact

On a multi-user server this makes latency and connectivity complaints on UDP-heavy workloads (games, VoIP) undiagnosable per user, while the same workloads are fully traceable on VLESS inbounds.

Scale of the gap on a live server

Same instance, same access log, over ~54k Hysteria2 lines and 200k VLESS lines:

Inbound lines with udp:
Hysteria2 54453 0
VLESS 200000 75650

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions