Skip to content

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.

json
"transport": { "type": "<ws|http|grpc|quic|httpupgrade>", ...variant fields }

type: "ws"

FieldTypeDefaultAllowed valuesDescription
pathstring//<path>WebSocket path.
headersbadoption.HTTPHeader{}{<header>: <value or list>}Extra upgrade-request headers.
max_early_datauint320<bytes>Maximum bytes of 0-RTT early data buffered before the WS handshake completes. 0 disables.
early_data_header_namestringSec-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)

FieldTypeDefaultAllowed valuesDescription
hostbadoption.Listable[string][][<hostname>]List of Host header values. Server uses the list for SNI matching; client picks one randomly per request.
pathstring//<path>HTTP path.
methodstringPUT<HTTP method>HTTP method. Standard transport uses PUT to discourage caches.
headersbadoption.HTTPHeader{}{<header>: <value or list>}Extra request headers.
idle_timeoutbadoption.Duration0<duration>Idle timeout — close the underlying HTTP connection after this much silence. 0 disables.
ping_timeoutbadoption.Duration0<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"

FieldTypeDefaultAllowed valuesDescription
service_namestring(required)<service path>gRPC service name.
idle_timeoutbadoption.Duration0<duration>Idle timeout. 0 disables.
ping_timeoutbadoption.Duration0<duration>Keepalive ping timeout. 0 disables PINGs.
permit_without_streamboolfalsetrue | falseAllow 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"

FieldTypeDefaultAllowed valuesDescription
hoststring(server address)<hostname>HTTP Host header.
pathstring//<path>HTTP path.
headersbadoption.HTTPHeader{}{<header>: <value or list>}Extra request headers.

Source: option/v2ray_transport.go:96-100 · pinned at v1.13.11 (553cfa1)

Examples

WebSocket + TLS:

json
{
  "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:

json
{
  "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):

json
{
  "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 (set tls.alpn: ["h3"]) which gives most of the same anti-DPI properties.
  • idle_timeout: 0 and ping_timeout: 0 together disable keepalive pings entirely. For long-lived connections behind NAT, set idle_timeout to something like "30s" so the underlying TCP connection sees periodic activity.
  • The host field on type: "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_name defaults to Sec-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 *Settings block, with TCP, mKCP, and SplitHTTP/XHTTP variants that sing-box doesn't have. See Transport — Xray-core.
  • mihomo distributes transport settings across per-protocol *-opts blocks on each proxy entry. See Transport — mihomo.

Source: option/v2ray_transport.go:70-100 · v1.13.11 (553cfa1)

Core Tutorial by Argsment