{"record":{"id":"64d51878891a4ccb","repo":"XTLS/Xray-core","slug":"failed-to-set-proxy-protocol-v-xver","errorCode":null,"errorMessage":"failed to set PROXY protocol v${xver}","messagePattern":"failed to set PROXY protocol v(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/trojan/server.go","lineNumber":523,"sourceCode":"\t\t\t\tif ipType == 0 {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"\\x20\\x00\\x00\\x00\"))) // v2 + LOCAL + UNSPEC + UNSPEC + 0 bytes\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif ipType == 4 {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"\\x21\\x11\\x00\\x0C\"))) // v2 + PROXY + AF_INET + STREAM + 12 bytes\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(remoteAddr).To4()))\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(localAddr).To4()))\n\t\t\t\t} else {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"\\x21\\x21\\x00\\x24\"))) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(remoteAddr).To16()))\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(localAddr).To16()))\n\t\t\t\t}\n\t\t\t\tp1, _ := strconv.ParseUint(remotePort, 10, 16)\n\t\t\t\tp2, _ := strconv.ParseUint(localPort, 10, 16)\n\t\t\t\tcommon.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)}))\n\t\t\t}\n\t\t\tif err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {\n\t\t\t\treturn errors.New(\"failed to set PROXY protocol v\", fb.Xver).Base(err).AtWarning()\n\t\t\t}\n\t\t}\n\t\tif err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn errors.New(\"failed to fallback request payload\").Base(err).AtInfo()\n\t\t}\n\t\treturn nil\n\t}\n\n\twriter := buf.NewWriter(connection)\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\t\tif err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn errors.New(\"failed to deliver response payload\").Base(err).AtInfo()\n\t\t}\n\t\treturn nil\n\t}\n","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/trojan/server.go#L505-L541","documentation":"Writing the synthesized PROXY protocol header (v1 text or v2 binary depending on fb.Xver) to the fallback connection failed on its first WriteMultiBuffer. The header carries the original client's addresses so the backend sees the real source IP.","triggerScenarios":"The fallback backend closed the connection immediately after accept (it does not understand PROXY protocol and resets), or the socket broke between the successful dial and this first write.","commonSituations":"xver is set to 1/2 but the backend (e.g. plain nginx http block without proxy_protocol listener) does not expect it, causing instant close; backend has proxy-protocol validation that rejects the header.","solutions":["Match fb.Xver with the backend: 0 if the backend does not speak PROXY protocol, 1 or 2 only if the listener is configured for proxy_protocol","On nginx: 'listen 8080 proxy_protocol;' and set_real_ip_from for the xray host","Check backend logs for the reason it closed right after accept"],"exampleFix":"// json trojan fallback with PROXY v2 for a backend that supports it\n\"fallbacks\": [{\"dest\": 8080, \"xver\": 2}]\n# nginx:\n# listen 127.0.0.1:8080 proxy_protocol;\n# set_real_ip_from 127.0.0.1;","handlingStrategy":"validation","validationCode":"// pick xver by backend capability, not by preference\nfunc proxyProtoVer(backendSupportsProxyProto bool) int {\n    if !backendSupportsProxyProto { return 0 }\n    return 2 // v2 unless the backend only parses v1\n}","typeGuard":null,"tryCatchPattern":"if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {\n    // backend rejected/closed on PROXY header: mismatch between xver and listener\n    return errors.New(\"failed to set PROXY protocol v\", fb.Xver).Base(err).AtWarning()\n}","preventionTips":["Set xver=0 unless the backend listener is explicitly proxy_protocol-enabled","On nginx pair xver:2 with 'listen ... proxy_protocol' plus set_real_ip_from","Document which fallback dests speak PROXY protocol directly in the config file"],"tags":["trojan","fallback","proxy-protocol"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}