{"record":{"id":"46f2b65797fb2abe","repo":"XTLS/Xray-core","slug":"failed-to-set-proxy-protocol-v-version","errorCode":null,"errorMessage":"failed to set PROXY protocol v{version}","messagePattern":"failed to set PROXY protocol v(.+?)","errorType":"exception","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"proxy/freedom/freedom.go","lineNumber":374,"sourceCode":"\t\t\tcommon.Interrupt(input)\n\t\t\tcommon.Interrupt(output)\n\t\t\terrors.LogInfo(ctx, \"closed blackholed connection to blocked target: \", *blockedDest)\n\t\t})\n\t\tdefer timer.Stop()\n\t\tdefer common.Close(output)\n\t\tif err := buf.Copy(input, buf.Discard); err != nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn nil\n\t}\n\tif h.config.ProxyProtocol > 0 && h.config.ProxyProtocol <= 2 {\n\t\tversion := byte(h.config.ProxyProtocol)\n\t\tsrcAddr := inbound.Source.RawNetAddr()\n\t\tdstAddr := conn.RemoteAddr()\n\t\theader := proxyproto.HeaderProxyFromAddrs(version, srcAddr, dstAddr)\n\t\tif _, err = header.WriteTo(conn); err != nil {\n\t\t\tconn.Close()\n\t\t\treturn errors.New(\"failed to set PROXY protocol v\", version).Base(err)\n\t\t}\n\t}\n\tdefer conn.Close()\n\terrors.LogInfo(ctx, \"connection opened to \", destination, \", local endpoint \", conn.LocalAddr(), \", remote endpoint \", conn.RemoteAddr())\n\n\tvar newCtx context.Context\n\tvar newCancel context.CancelFunc\n\tif session.TimeoutOnlyFromContext(ctx) {\n\t\tnewCtx, newCancel = context.WithCancel(context.Background())\n\t}\n\n\tplcy := h.policy()\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, func() {\n\t\tcancel()\n\t\tif newCancel != nil {\n\t\t\tnewCancel()\n\t\t}","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/freedom/freedom.go#L356-L392","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n\"settings\": { \"proxyProtocol\": 2 }  // target has no PROXY support\n// after\n\"settings\": { }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"```go\nif err := h.Process(ctx, link, dialer); err != nil {\n    if strings.Contains(err.Error(), \"failed to set PROXY protocol\") {\n        // conn already closed; verify server expects the protocol/version\n    }\n}\n```","preventionTips":["Enable proxyProtocol only when the receiver supports it","Match v1/v2 exactly on both ends","Document protocol expectations per port"],"tags":["freedom","proxy-protocol","haproxy","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}