XTLS/Xray-core · error
failed to process outbound traffic
Error message
failed to process outbound traffic
What it means
The primary outbound dispatch failure: the underlying proxy's Process(ctx, link, h) returned a non-nil error that is not one of the benign causes (io.EOF, io.ErrClosedPipe, context.Canceled), which are normalized to nil just above. The logged message wraps the real cause via .Base; the writer is interrupted and the error reported to the session originator.
Source
Thrown at app/proxyman/outbound/handler.go:253
return
}
if h.mux.Enabled {
test(h.mux.Dispatch(ctx, link))
return
}
}
out:
err := h.proxy.Process(ctx, link, h)
var errC error
if err != nil {
errC = errors.Cause(err)
if goerrors.Is(errC, io.EOF) || goerrors.Is(errC, io.ErrClosedPipe) || goerrors.Is(errC, context.Canceled) {
err = nil
}
}
if err != nil {
// Ensure outbound ray is properly closed.
err := errors.New("failed to process outbound traffic").Base(err)
session.SubmitOutboundErrorToOriginator(ctx, err)
errors.LogInfo(ctx, err.Error())
common.Interrupt(link.Writer)
} else {
if errC != nil && goerrors.Is(errC, io.ErrClosedPipe) {
common.Interrupt(link.Writer)
} else {
common.Close(link.Writer)
}
}
common.Interrupt(link.Reader)
}
func (h *Handler) DestIpAddress() net.IP {
return internet.DestIpAddress()
}
// Dial implements internet.Dialer.View on GitHub (pinned to 7d214f8b09)
Solutions
- Inspect the full log line: the Base() error names the real failure (timeout, TLS, handshake, auth) — fix that layer first.
- Verify client/server protocol settings match exactly (protocol version, UUID/password, encryption, transport, TLS/REALITY parameters, SNI, path).
- Test raw reachability of the server's transport port (tcping/nc) and, for TLS/REALITY, confirm certificate and destination config; check server-side logs for the matching failure.
- For timeout-type inner errors, review sockopt dialer settings, mark/routing table, and MTU; for reset errors, check for ISP interference and switch transport (e.g. to grpc/ws over TLS).
- Reproduce with loglevel debug on both ends to capture the exact stage that fails.
Example fix
// no code fix; diagnosis example
// log: [Info] proxy/vless/outbound: failed to process outbound traffic > tls: handshake failure
// fix: align client streamSettings with server, e.g.
// before: "security": "tls", "tlsSettings": { "serverName": "wrong.example" }
// after: "security": "tls", "tlsSettings": { "serverName": "actual.example" } Defensive patterns
Strategy: retry
Validate before calling
// Pre-validate the remote before routing user traffic through it
if err := probeOutbound(ctx, handlerTag, probeDest); err != nil {
return routeViaFallback(ctx, link)
} Try / catch
// Classify cause before deciding: benign closes vs real failures
if err := dispatch(ctx, link); err != nil && strings.Contains(err.Error(), "failed to process outbound traffic") {
switch {
case isTimeoutCause(err): return retryWithBackoff(ctx, link, 3)
case isAuthCause(err): return nil // config problem; surface to user, no retry
default: return fallbackOutbound.Dispatch(ctx, link)
}
} Prevention
- Validate protocol/transport/TLS settings against the server before going live
- Run active health probes (api observatory or balancer with leastping) on outbounds
- Treat resets/timeouts differently: retry the former, fix config for the latter
- Keep a known-good fallback outbound for automatic degradation
When it happens
Trigger: h.proxy.Process fails for a connection that already passed DNS/mux handling: protocol errors from the remote server (handshake failure, auth failure, unsupported protocol), network errors dialing or mid-stream (connection reset, timeout), TLS failures, or the remote proxy closing with an error. Any cause except io.EOF / io.ErrClosedPipe / context.Canceled reaches this branch.
Common situations: Wrong UUID/password or altered protocol settings vs the server, TLS certificate/reality misconfiguration, server reachable but behind a CDN that rejects the path, NAT/firewall resetting long connections, or clock skew breaking time-bound handshakes. This is the generic envelope, so the Base cause in the log is the actual diagnostic.
Related errors
- cannot dial remote address
- cannot finish connection
- failed to resolve ip for target ${domain}
- failed to process mux outbound traffic
- failed to get outbound handler with tag: ${tag}
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/c6b47e7a3b291c42.
Report an issue: GitHub.