XTLS/Xray-core · error · errors.Error
failed to set PROXY protocol v{version}
Error message
failed to set PROXY protocol v{version} What it means
freedom is configured with settings.proxyProtocol (v1 or v2) and failed while writing the HAProxy PROXY-protocol header onto the freshly dialed connection. The header carries the inbound source address and the remote destination; a write failure at this point means the socket broke between dial success and first write, so the conn is closed and the error wrapped with the version byte.
Source
Thrown at proxy/freedom/freedom.go:374
common.Interrupt(input)
common.Interrupt(output)
errors.LogInfo(ctx, "closed blackholed connection to blocked target: ", *blockedDest)
})
defer timer.Stop()
defer common.Close(output)
if err := buf.Copy(input, buf.Discard); err != nil {
return nil
}
return nil
}
if h.config.ProxyProtocol > 0 && h.config.ProxyProtocol <= 2 {
version := byte(h.config.ProxyProtocol)
srcAddr := inbound.Source.RawNetAddr()
dstAddr := conn.RemoteAddr()
header := proxyproto.HeaderProxyFromAddrs(version, srcAddr, dstAddr)
if _, err = header.WriteTo(conn); err != nil {
conn.Close()
return errors.New("failed to set PROXY protocol v", version).Base(err)
}
}
defer conn.Close()
errors.LogInfo(ctx, "connection opened to ", destination, ", local endpoint ", conn.LocalAddr(), ", remote endpoint ", conn.RemoteAddr())
var newCtx context.Context
var newCancel context.CancelFunc
if session.TimeoutOnlyFromContext(ctx) {
newCtx, newCancel = context.WithCancel(context.Background())
}
plcy := h.policy()
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, func() {
cancel()
if newCancel != nil {
newCancel()
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Confirm the destination server actually speaks PROXY protocol and expects it on this port
- Match versions exactly: proxyProtocol:1 for servers expecting v1 text, 2 for binary v2
- If the server does not want it, remove settings.proxyProtocol from the outbound
- Check for middleboxes/LB in path that strip or reject the header
Example fix
// before
"settings": { "proxyProtocol": 2 } // target has no PROXY support
// after
"settings": { } Defensive patterns
Strategy: validation
Try / catch
```go
if err := h.Process(ctx, link, dialer); err != nil {
if strings.Contains(err.Error(), "failed to set PROXY protocol") {
// conn already closed; verify server expects the protocol/version
}
}
``` Prevention
- Enable proxyProtocol only when the receiver supports it
- Match v1/v2 exactly on both ends
- Document protocol expectations per port
When it happens
Trigger: settings.proxyProtocol: 1 or 2 in the freedom outbound, and the target closes/RESETs the connection immediately after accept (non-PROXY-protocol-aware server), or a middlebox kills the session on first bytes.
Common situations: Sending PROXY protocol to a server that does not expect it (server RSTs the malformed first line), proxyProtocol value out of sync between sender and receiver versions (v1 vs v2), or an aggressive firewall resetting new flows.
Related errors
- unsupported domain strategy: {}
- Invalid PacketsFrom
- PacketsFrom can't be 0
- Length can't be empty
- LengthMin can't be 0
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/46f2b65797fb2abe.
Report an issue: GitHub.