nats-io/nats-server · warning
failed to read IPv6 address data: %w
Error message
failed to read IPv6 address data: %w
What it means
The AF_INET6 header declared a valid (>=36 byte) address length, but io.ReadFull could not read that many bytes from the connection, so the IPv6 address payload arrived incomplete. The wrapped underlying I/O error is preserved via %w.
Source
Thrown at server/client_proxyproto.go:407
return nil, fmt.Errorf("failed to read IPv4 address data: %w", err)
}
return &proxyProtoAddr{
srcIP: net.IP(addrData[0:4]),
dstIP: net.IP(addrData[4:8]),
srcPort: binary.BigEndian.Uint16(addrData[8:10]),
dstPort: binary.BigEndian.Uint16(addrData[10:12]),
}, nil
}
// parseIPv6Addr parses IPv6 address data from PROXY protocol header
func parseIPv6Addr(conn net.Conn, addrLen uint16) (*proxyProtoAddr, error) {
// IPv6: 16 (src IP) + 16 (dst IP) + 2 (src port) + 2 (dst port) = 36 bytes minimum
if addrLen < proxyProtoAddrSizeIPv6 {
return nil, fmt.Errorf("IPv6 address data too short: %d bytes", addrLen)
}
addrData := make([]byte, addrLen)
if _, err := io.ReadFull(conn, addrData); err != nil {
return nil, fmt.Errorf("failed to read IPv6 address data: %w", err)
}
return &proxyProtoAddr{
srcIP: net.IP(addrData[0:16]),
dstIP: net.IP(addrData[16:32]),
srcPort: binary.BigEndian.Uint16(addrData[32:34]),
dstPort: binary.BigEndian.Uint16(addrData[34:36]),
}, nil
}
View on GitHub (pinned to 3a66a489d2)
Solutions
- Have the proxy send the whole PROXY v2 header in one write to reduce the partial-read window.
- Treat as transient: reconnect; inspect the wrapped error with errors.Is(err, io.ErrUnexpectedEOF) vs timeout to decide.
- Verify nothing between LB and server (idle timeouts, security appliances) is cutting short connections immediately after header write.
Defensive patterns
Strategy: retry
Type guard
func isHeaderTruncation(err error) bool {
return errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, net.ErrClosed)
} Try / catch
if err != nil {
var terr net.Error
if errors.As(err, &terr) && terr.Timeout() {
return retryWithBackoff()
}
if strings.Contains(err.Error(), "failed to read IPv6 address data") {
return reconnect() // peer dropped mid-header
}
} Prevention
- Write the full PROXY v2 header atomically from the proxy side
- Monitor for RST/close spikes between LB and server
- Avoid aggressive idle timeouts that can sever connections right after the header
When it happens
Trigger: Connection closed or timed out after the v2 header was partially written; the peer sent only the 16-byte signature + length and then dropped; scanner/probe sent a truncated header.
Common situations: Health checks against a PROXY listener; unstable networks between LB and NATS; proxies split writes across packets and the client disconnects between them.
Related errors
- failed to read v2 signature: %w
- failed to read v2 header: %w
- failed to read PROXY protocol header: %w
- failed to discard LOCAL command address data: %w
- failed to discard UNSPEC address address data: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/674438ddfa43a5ae.
Report an issue: GitHub.