{"record":{"id":"c8adeaa22feac1e7","repo":"fatedier/frp","slug":"failed-to-write-proxy-protocol-header-v","errorCode":null,"errorMessage":"failed to write proxy protocol header: %v","messagePattern":"failed to write proxy protocol header: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/net/proxyprotocol.go","lineNumber":42,"sourceCode":"\nfunc BuildProxyProtocolHeaderStruct(srcAddr, dstAddr net.Addr, version string) *pp.Header {\n\tvar versionByte byte\n\tif version == \"v1\" {\n\t\tversionByte = 1\n\t} else {\n\t\tversionByte = 2 // default to v2\n\t}\n\treturn pp.HeaderProxyFromAddrs(versionByte, srcAddr, dstAddr)\n}\n\nfunc BuildProxyProtocolHeader(srcAddr, dstAddr net.Addr, version string) ([]byte, error) {\n\th := BuildProxyProtocolHeaderStruct(srcAddr, dstAddr, version)\n\n\t// Convert header to bytes using a buffer\n\tvar buf bytes.Buffer\n\t_, err := h.WriteTo(&buf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to write proxy protocol header: %v\", err)\n\t}\n\treturn buf.Bytes(), nil\n}\n","sourceCodeStart":24,"sourceCodeEnd":46,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/util/net/proxyprotocol.go#L24-L46","documentation":"BuildProxyProtocolHeader serializes a proxy-protocol header struct (v1 or v2, built by HeaderProxyFromAddrs) into a bytes.Buffer via WriteTo. Because the destination is an in-memory bytes.Buffer, WriteTo only fails if the header object itself refuses to encode — e.g. an address family that the proxy protocol cannot represent. Real network failures cannot occur here.","triggerScenarios":"srcAddr/dstAddr with a network type the proxy protocol library cannot map to a v1/v2 family (an exotic net.Addr implementation rather than TCPAddr/UDPAddr/UnixAddr), since v1 text encoding or v2 binary encoding of unsupported families fails.","commonSituations":"Custom net.Conn wrappers whose LocalAddr/RemoteAddr return bespoke address types; essentially never with standard TCP conns.","solutions":["Pass plain *net.TCPAddr (or UDP/Unix addrs) as srcAddr/dstAddr.","If you wrap conns, make sure LocalAddr/RemoteAddr still return standard address types.","On error, fall back to omitting the proxy protocol header for that connection."],"exampleFix":"// before\nhdr, err := netpkg.BuildProxyProtocolHeader(customAddr{network: \"weird\"}, dst, \"v2\")\n\n// after\nhdr, err := netpkg.BuildProxyProtocolHeader(conn.RemoteAddr().(*net.TCPAddr), conn.LocalAddr().(*net.TCPAddr), \"v2\")","handlingStrategy":"fallback","validationCode":"// ensure addresses are proxy-protocol representable before building the header\nfunc proxyProtocolRepresentable(addr net.Addr) bool {\n    switch addr.(type) {\n    case *net.TCPAddr, *net.UDPAddr, *net.UnixAddr:\n        return true\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":"header, err := netpkg.BuildProxyProtocolHeader(srcAddr, dstAddr, version)\nif err != nil {\n    // degrade gracefully: serve the connection without PROXY info\n    log.Warnf(\"proxy protocol header build failed: %v\", err)\n    header = nil\n}","preventionTips":["Pass standard TCP/UDP/Unix address types; never bespoke net.Addr implementations.","Keep conn wrappers transparent: LocalAddr/RemoteAddr must return the underlying standard types.","Treat failure as 'omit header' rather than killing the connection."],"tags":["proxy-protocol","encoding","network"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}