{"record":{"id":"1505dee0c5774cf5","repo":"nats-io/nats-server","slug":"ipv4-address-data-too-short-d-bytes","errorCode":null,"errorMessage":"IPv4 address data too short: %d bytes","messagePattern":"IPv4 address data too short: (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/client_proxyproto.go","lineNumber":385,"sourceCode":"\t\t// UNSPEC family with PROXY command is valid but rare\n\t\t// Just skip the address data\n\t\tif addrLen > 0 {\n\t\t\tif _, err := io.CopyN(io.Discard, conn, int64(addrLen)); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to discard UNSPEC address address data: %w\", err)\n\t\t\t}\n\t\t}\n\t\treturn nil, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"%w: unsupported address family 0x%02x\", errProxyProtoUnsupported, family)\n\t}\n\treturn addr, err\n}\n\n// parseIPv4Addr parses IPv4 address data from PROXY protocol header\nfunc parseIPv4Addr(conn net.Conn, addrLen uint16) (*proxyProtoAddr, error) {\n\t// IPv4: 4 (src IP) + 4 (dst IP) + 2 (src port) + 2 (dst port) = 12 bytes minimum\n\tif addrLen < proxyProtoAddrSizeIPv4 {\n\t\treturn nil, fmt.Errorf(\"IPv4 address data too short: %d bytes\", addrLen)\n\t}\n\taddrData := make([]byte, addrLen)\n\tif _, err := io.ReadFull(conn, addrData); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read IPv4 address data: %w\", err)\n\t}\n\treturn &proxyProtoAddr{\n\t\tsrcIP:   net.IP(addrData[0:4]),\n\t\tdstIP:   net.IP(addrData[4:8]),\n\t\tsrcPort: binary.BigEndian.Uint16(addrData[8:10]),\n\t\tdstPort: binary.BigEndian.Uint16(addrData[10:12]),\n\t}, nil\n}\n\n// parseIPv6Addr parses IPv6 address data from PROXY protocol header\nfunc parseIPv6Addr(conn net.Conn, addrLen uint16) (*proxyProtoAddr, error) {\n\t// IPv6: 16 (src IP) + 16 (dst IP) + 2 (src port) + 2 (dst port) = 36 bytes minimum\n\tif addrLen < proxyProtoAddrSizeIPv6 {\n\t\treturn nil, fmt.Errorf(\"IPv6 address data too short: %d bytes\", addrLen)","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/client_proxyproto.go#L367-L403","documentation":"parseIPv4Addr requires at least proxyProtoAddrSizeIPv4 (12) bytes of address data for an AF_INET PROXY v2 header (4 src IP + 4 dst IP + 2 src port + 2 dst port). The declared addrLen from the header was smaller, so the payload cannot possibly contain a valid IPv4 endpoint pair and parsing is aborted immediately without reading from the connection.","triggerScenarios":"A v2 PROXY header with command/family byte 0x11 but an address-length field less than 12 bytes, e.g. a truncated or hand-crafted header, or a sender that set the length to the IP-only size (8) and forgot the ports.","commonSituations":"Custom or buggy proxy implementations writing the wrong length field; packets truncated by MTU/fragmentation bugs; fuzz traffic; header corruption from TCP interception.","solutions":["Fix the proxy to always declare 12 bytes for AF_INET (or 36 for AF_INET6) in the length field of the v2 header.","Update/replace the middleware emitting PROXY v2 headers if it is a home-grown implementation.","If you control the connecting client, switch it to PROXY v1 or plain TCP, since this server validates lengths strictly."],"exampleFix":"// before: custom proxy writes only the two IPs\nlenBuf := make([]byte, 2)\nbinary.BigEndian.PutUint16(lenBuf, 8)\n// after: include ports (12 bytes for IPv4)\nbinary.BigEndian.PutUint16(lenBuf, 12)","handlingStrategy":"validation","validationCode":"// pre-validate before sending a v2 header\ncanonical := map[byte]uint16{0x11: 12, 0x21: 36}\nif want, ok := canonical[hdr[14]]; !ok || addrLen < want {\n    return fmt.Errorf(\"addrLen %d too small for family 0x%02x\", addrLen, hdr[14])\n}","typeGuard":"func validIPv4AddrLen(n uint16) bool { return n >= 12 }","tryCatchPattern":null,"preventionTips":["Test your proxy header writer against haproxy's PROXY v2 spec (12/36/216-byte lengths)","Never hardcode IPv4 lengths when the upstream address family can be IPv6","Add integration tests that round-trip v2 headers through your proxy"],"tags":["proxy-protocol","protocol-parsing","validation"],"backgroundTag":"proxy-protocol-header-too-short","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}