XTLS/Xray-core · error · errors.Error

UDP is not supported by HTTP outbound

Error message

UDP is not supported by HTTP outbound

What it means

The HTTP outbound only implements HTTP CONNECT, which is a TCP-tunnel mechanism; a session with Network == UDP cannot be carried. The handler rejects UDP targets outright instead of attempting a bogus CONNECT.

Source

Thrown at proxy/http/client.go:81

		policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
		header:        config.Header,
	}, nil
}

// Process implements proxy.Outbound.Process. We first create a socket tunnel via HTTP CONNECT method, then redirect all inbound traffic to that tunnel.
func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
	outbounds := session.OutboundsFromContext(ctx)
	ob := outbounds[len(outbounds)-1]
	if !ob.Target.IsValid() {
		return errors.New("target not specified.")
	}
	ob.Name = "http"
	ob.CanSpliceCopy = 2
	target := ob.Target
	targetAddr := target.NetAddr()

	if target.Network == net.Network_UDP {
		return errors.New("UDP is not supported by HTTP outbound")
	}

	server := c.server
	dest := server.Destination
	user := server.User
	var conn stat.Connection

	mbuf, _ := link.Reader.ReadMultiBuffer()
	len := mbuf.Len()
	firstPayload := bytespool.Alloc(len)
	mbuf, _ = buf.SplitBytes(mbuf, firstPayload)
	firstPayload = firstPayload[:len]

	buf.ReleaseMulti(mbuf)
	defer bytespool.Free(firstPayload)

	header, err := fillRequestHeader(ctx, c.header)
	if err != nil {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Route UDP elsewhere: point UDP traffic at a SOCKS5u/freedom outbound via a routing rule with "network": "udp"
  2. Or restrict the HTTP outbound's routing rule to "network": "tcp"
  3. Alternatively block QUIC (drop udp:443) so browsers fall back to TCP/H2

Example fix

// routing.json — send udp elsewhere
{ "type": "field", "network": "udp", "outboundTag": "direct-udp" }
Defensive patterns

Strategy: validation

Validate before calling

```go
if target.Network == net.Network_UDP {
    // dispatch to a UDP-capable outbound (socks5u/freedom) instead
}
```

Type guard

```go
func isUDPSession(target net.Destination) bool {
    return target.Network == net.Network_UDP
}
```

Prevention

When it happens

Trigger: A UDP flow (DNS, QUIC, WireGuard, voice) is routed to an outbound with "protocol":"http". Typical triggers: browser QUIC/HTTP3 traffic (UDP 443) matching the default route, or DNS leaked into the proxy chain.

Common situations: Clients with HTTP3/QUIC enabled behind an HTTP-only outbound; routing rules with network field unset (defaults to tcp+udp) pointing at the HTTP outbound.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/a990babff043e323. Report an issue: GitHub.