Skip to content

TUIC — sing-box

sing-box implements TUIC v5 — the modern, UUID+password form. The historic v4 "token" form is not supported. TUIC always runs over QUIC, so the embedded tls block is required.

Inbound

type: "tuic" inbound:

FieldTypeDefaultAllowed valuesDescription
users[]TUICUser[][TUICUser]Accepted users. Each carries a UUID + password pair.
congestion_controlstringcubiccubic | new_reno | bbrQUIC congestion-control algorithm. Setting it here only changes the server-side outgoing direction; clients pick their own.
auth_timeoutbadoption.Duration3s<duration>How long to wait for the client to complete the authentication frame before closing the QUIC connection.
zero_rtt_handshakeboolfalsetrue | falseAccept 0-RTT TLS handshakes. Enables slightly faster connect at the cost of replay-attack resistance for the first 0-RTT-payload window.
heartbeatbadoption.Duration10s<duration>Interval between QUIC PING frames the server sends to keep NAT mappings alive.

Source: option/tuic.go:5-13 · pinned at v1.13.11 (553cfa1)

The struct embeds ListenOptions and InboundTLSOptionsContainer. A TLS configuration is required.

users[]

FieldTypeDefaultAllowed valuesDescription
namestring(unset)<string>Display name used in stats and logs.
uuidstring(required)<UUID>Client UUID.
passwordstring(required)<string>Client password.

Source: option/tuic.go:15-19 · pinned at v1.13.11 (553cfa1)

Outbound

type: "tuic" outbound:

FieldTypeDefaultAllowed valuesDescription
uuidstring(required)<UUID>User UUID accepted by the server.
passwordstring(required)<string>User password.
congestion_controlstringcubiccubic | new_reno | bbrQUIC congestion-control algorithm for client-to-server direction.
udp_relay_modestringnativenative | quicHow UDP packets are tunneled. `native` uses QUIC datagrams; `quic` wraps each UDP packet in a dedicated QUIC stream. `native` is faster; `quic` survives middleboxes that drop QUIC datagrams.
udp_over_streamboolfalsetrue | falseUse the UDP-over-stream framing introduced for TUIC clients that talk to QUIC stacks without datagram support. Negotiated; both sides must enable it.
zero_rtt_handshakeboolfalsetrue | falseUse 0-RTT TLS handshake on reconnect.
heartbeatbadoption.Duration10s<duration>QUIC PING interval.
networkNetworkList(tcp+udp)tcp | udp | Restrict to TCP-only or UDP-only.

Source: option/tuic.go:21-33 · pinned at v1.13.11 (553cfa1)

Embeds DialerOptions, ServerOptions, and OutboundTLSOptionsContainer.

Examples

Inbound:

json
{
  "inbounds": [
    {
      "type": "tuic",
      "tag": "tuic-in",
      "listen": "::",
      "listen_port": 443,
      "users": [
        { "name": "alice", "uuid": "a3482e88-686a-4a58-8126-99c9df64b7bf", "password": "<password>" }
      ],
      "congestion_control": "bbr",
      "auth_timeout": "3s",
      "heartbeat": "10s",
      "tls": {
        "enabled": true,
        "alpn": ["h3"],
        "certificate_path": "/etc/ssl/cert.pem",
        "key_path": "/etc/ssl/key.pem"
      }
    }
  ]
}

Outbound:

json
{
  "outbounds": [
    {
      "type": "tuic",
      "tag": "tuic-out",
      "server": "example.com",
      "server_port": 443,
      "uuid": "a3482e88-686a-4a58-8126-99c9df64b7bf",
      "password": "<password>",
      "congestion_control": "bbr",
      "udp_relay_mode": "native",
      "zero_rtt_handshake": false,
      "heartbeat": "10s",
      "tls": { "enabled": true, "server_name": "example.com", "alpn": ["h3"] }
    }
  ]
}

Notes

  • udp_relay_mode: native is the recommended default. Switch to quic only if you are running across a middlebox that DPI-drops QUIC datagrams.
  • zero_rtt_handshake: true enables 0-RTT on reconnect. The first connection still does a full handshake. The optimization is most visible on mobile networks that frequently re-resolve / reconnect.
  • auth_timeout is enforced on the server. If the inbound sees no auth frame within this window, the QUIC connection is closed silently.
  • udp_over_stream is a compatibility knob — there is no TUIC server spec deviation involved; both sides simply have to agree.

Cross-core notes

  • Xray-core does not support TUIC. See TUIC — Xray-core.
  • mihomo uses field names in kebab-case (congestion-controller, udp-relay-mode), supports the older token form for compatibility, and exposes more QUIC tuning knobs (window sizes, MTU discovery, BBR profile). It also has a unique top-level tuic-server block as an alternative way to declare an inbound. See TUIC — mihomo.

Source: option/tuic.go:5-33 · v1.13.11 (553cfa1)

Core Tutorial by Argsment