Transport — sing-box
sing-box's transport options live in the transport block embedded on every TLS-capable inbound and outbound. The block is polymorphic: the type field selects one of five transport variants, and the matching subset of fields applies.
"transport": { "type": "<ws|http|grpc|quic|httpupgrade>", ...variant fields }type: "ws"
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
path | string | / | /<path> | WebSocket path. |
headers | badoption.HTTPHeader | {} | {<header>: <value or list>} | Extra upgrade-request headers. |
max_early_data | uint32 | 0 | <bytes> | Maximum bytes of 0-RTT early data buffered before the WS handshake completes. 0 disables. |
early_data_header_name | string | Sec-WebSocket-Protocol | <header name> | HTTP header carrying base64-encoded early data when the server expects it under a non-standard name. |
Source: option/v2ray_transport.go:79-84 · pinned at v1.13.11 (553cfa1)
type: "http" (HTTP/2)
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
host | badoption.Listable[string] | [] | [<hostname>] | List of Host header values. Server uses the list for SNI matching; client picks one randomly per request. |
path | string | / | /<path> | HTTP path. |
method | string | PUT | <HTTP method> | HTTP method. Standard transport uses PUT to discourage caches. |
headers | badoption.HTTPHeader | {} | {<header>: <value or list>} | Extra request headers. |
idle_timeout | badoption.Duration | 0 | <duration> | Idle timeout — close the underlying HTTP connection after this much silence. 0 disables. |
ping_timeout | badoption.Duration | 0 | <duration> | Timeout for the HTTP/2 PING probe response. 0 disables PINGs. |
Source: option/v2ray_transport.go:70-77 · pinned at v1.13.11 (553cfa1)
The HTTP transport runs over HTTP/2 by default. With tls.alpn: ["h3"] on the surrounding TLS block, the transport uses HTTP/3 instead.
type: "grpc"
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
service_name | string | (required) | <service path> | gRPC service name. |
idle_timeout | badoption.Duration | 0 | <duration> | Idle timeout. 0 disables. |
ping_timeout | badoption.Duration | 0 | <duration> | Keepalive ping timeout. 0 disables PINGs. |
permit_without_stream | bool | false | true | false | Allow PINGs with no active stream. |
Source: option/v2ray_transport.go:88-94 · pinned at v1.13.11 (553cfa1)
type: "quic"
The QUIC transport struct has no user-facing fields — it's just { "type": "quic" }. All QUIC tuning happens at the protocol layer (Hysteria2 / TUIC have their own native QUIC stacks).
type: "httpupgrade"
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
host | string | (server address) | <hostname> | HTTP Host header. |
path | string | / | /<path> | HTTP path. |
headers | badoption.HTTPHeader | {} | {<header>: <value or list>} | Extra request headers. |
Source: option/v2ray_transport.go:96-100 · pinned at v1.13.11 (553cfa1)
Examples
WebSocket + TLS:
{
"outbounds": [{
"type": "vless",
"server": "example.com",
"server_port": 443,
"uuid": "...",
"tls": {
"enabled": true,
"server_name": "example.com"
},
"transport": {
"type": "ws",
"path": "/vl",
"headers": { "Host": "example.com" }
}
}]
}gRPC + REALITY:
{
"outbounds": [{
"type": "vless",
"server": "example.com",
"server_port": 443,
"uuid": "...",
"tls": {
"enabled": true,
"server_name": "www.cloudflare.com",
"utls": { "enabled": true, "fingerprint": "chrome" },
"reality": { "enabled": true, "public_key": "...", "short_id": "..." }
},
"transport": {
"type": "grpc",
"service_name": "GunService",
"idle_timeout": "60s",
"ping_timeout": "20s",
"permit_without_stream": true
}
}]
}HTTP/3 (HTTP transport over h3):
{
"outbounds": [{
"type": "vless",
"server": "example.com",
"server_port": 443,
"uuid": "...",
"tls": {
"enabled": true,
"server_name": "example.com",
"alpn": ["h3"]
},
"transport": {
"type": "http",
"host": ["example.com"],
"path": "/h3",
"method": "PUT"
}
}]
}Notes
- sing-box does not ship a separate SplitHTTP / XHTTP transport. The closest equivalent is
type: "http"over HTTP/3 (settls.alpn: ["h3"]) which gives most of the same anti-DPI properties. idle_timeout: 0andping_timeout: 0together disable keepalive pings entirely. For long-lived connections behind NAT, setidle_timeoutto something like"30s"so the underlying TCP connection sees periodic activity.- The
hostfield ontype: "http"is a list. The server uses it for SNI matching (any value matches); the client picks one randomly per request, useful when the upstream load balancer routes by Host header. - WebSocket
early_data_header_namedefaults toSec-WebSocket-Protocol— the same header V2Ray uses. Override only when the upstream proxy strips that header.
Cross-core notes
- Xray-core uses
streamSettings.network+ a per-transport*Settingsblock, with TCP, mKCP, and SplitHTTP/XHTTP variants that sing-box doesn't have. See Transport — Xray-core. - mihomo distributes transport settings across per-protocol
*-optsblocks on each proxy entry. See Transport — mihomo.
Source: option/v2ray_transport.go:70-100 · v1.13.11 (553cfa1)
