{"record":{"id":"39be6c341c29a155","repo":"nats-io/nats-server","slug":"ipv6-address-data-too-short-d-bytes","errorCode":null,"errorMessage":"IPv6 address data too short: %d bytes","messagePattern":"IPv6 address data too short: (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/client_proxyproto.go","lineNumber":403,"sourceCode":"\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)\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 IPv6 address data: %w\", err)\n\t}\n\treturn &proxyProtoAddr{\n\t\tsrcIP:   net.IP(addrData[0:16]),\n\t\tdstIP:   net.IP(addrData[16:32]),\n\t\tsrcPort: binary.BigEndian.Uint16(addrData[32:34]),\n\t\tdstPort: binary.BigEndian.Uint16(addrData[34:36]),\n\t}, nil\n}\n","sourceCodeStart":385,"sourceCodeEnd":416,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/client_proxyproto.go#L385-L416","documentation":"parseIPv6Addr requires at least proxyProtoAddrSizeIPv6 (36) bytes of address data for an AF_INET6 v2 header (16 src IP + 16 dst IP + 2 src port + 2 dst port). The header's declared addrLen was smaller, so the payload cannot hold a valid IPv6 endpoint pair and parsing fails without reading.","triggerScenarios":"A v2 PROXY header with family byte 0x21 but address-length less than 36, e.g. a sender copying the IPv4 length (12) or writing only one address (16/18 bytes).","commonSituations":"Proxies that hardcode IPv4 header sizes and get an IPv6 upstream connection; hand-rolled test harnesses; buggy header builders in custom TCP middleware.","solutions":["Correct the proxy to declare 36 bytes of address data for AF_INET6 v2 headers.","Prefer forcing IPv4 upstream (set resolver/address family) so the proxy emits AF_INET headers if it only supports them correctly.","Update the emitting proxy software if it is a known bug in an older version."],"exampleFix":"// before\nbinary.BigEndian.PutUint16(lenBuf, 12) // IPv4 length used for IPv6\n// after\nbinary.BigEndian.PutUint16(lenBuf, 36) // 16+16+2+2","handlingStrategy":"validation","validationCode":"if hdr[14] == 0x21 && addrLen < 36 {\n    return fmt.Errorf(\"IPv6 v2 header needs >=36 addr bytes, got %d\", addrLen)\n}","typeGuard":"func validIPv6AddrLen(n uint16) bool { return n >= 36 }","tryCatchPattern":null,"preventionTips":["Compute the v2 address length from the family: 12 for IPv4, 36 for IPv6","Pin the proxy to IPv4 upstreams if it mishandles IPv6 lengths","Unit-test header building for both address families"],"tags":["proxy-protocol","ipv6","protocol-parsing"],"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"}