nats-io/nats-server · warning
failed to discard LOCAL command address data: %w
Error message
failed to discard LOCAL command address data: %w
What it means
After a LOCAL command (health check) is parsed, the library must still consume addrLen bytes of address payload from the connection so the stream stays in sync. This error wraps whatever failure occurred while discarding those bytes (io.CopyN error, usually EOF/timeout/reset).
Source
Thrown at server/client_proxyproto.go:342
if version != proxyProtoV2Ver {
return nil, fmt.Errorf("%w: invalid version 0x%02x", errProxyProtoInvalid, version)
}
// Parse address family and protocol
famProto := header[1]
family := famProto & proxyProtoFamilyMask
protocol := famProto & proxyProtoProtoMask
// Parse address length (big-endian uint16)
addrLen := binary.BigEndian.Uint16(header[2:4])
// Handle LOCAL command (health check)
if command == proxyProtoCmdLocal {
// For LOCAL, we should skip the address data if any
if addrLen > 0 {
// Discard the address data
if _, err := io.CopyN(io.Discard, conn, int64(addrLen)); err != nil {
return nil, fmt.Errorf("failed to discard LOCAL command address data: %w", err)
}
}
return nil, nil // nil addr indicates LOCAL command
}
// Handle PROXY command
if command != proxyProtoCmdProxy {
return nil, fmt.Errorf("unknown PROXY protocol command: 0x%02x", command)
}
// Validate protocol (we only support STREAM/TCP)
if protocol != proxyProtoProtoStream {
return nil, fmt.Errorf("%w: only STREAM protocol supported", errProxyProtoUnsupported)
}
// Parse address data based on family
var addr *proxyProtoAddr
var err errorView on GitHub (pinned to 3a66a489d2)
Solutions
- Check the wrapped error: EOF/unexpected EOF means the sender truncated the header payload
- Ensure health-check senders transmit the full address section matching the declared length
- Increase the read deadline if the sender is slow rather than broken
- Retry the connection — this is typically transient on flaky networks
Example fix
// before: sender sends LOCAL header claiming 12 bytes but closes early conn.Close() // after: send the full advertised payload write(header); write(addrBytes) // addrBytes len == addrLen
Defensive patterns
Strategy: try-catch
Try / catch
addr, err := readProxyProtoHeader(conn)
if err != nil && strings.Contains(err.Error(), "failed to discard LOCAL command address data") {
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(context.DeadlineExceeded, err) {
return errRetryable
}
return err
} Prevention
- Ensure LOCAL health-check senders include the full address section they declare
- Set a realistic read deadline for slow networks
- Monitor for unexpected EOF spikes indicating truncated headers
- Keep proxy firmware updated — old versions truncate LOCAL payloads
When it happens
Trigger: Peer sends a v2 header declaring command LOCAL with addrLen>0 but closes, times out (proxyProtoReadDeadline), or resets the connection before the declared address bytes can be read; or sends fewer bytes than advertised in the length field.
Common situations: Health checker abruptly closing after sending a LOCAL header; a truncated packet from a buggy proxy; network drop mid-header; aggressive client timeouts.
Related errors
- failed to read v2 signature: %w
- failed to read v2 header: %w
- failed to read PROXY protocol header: %w
- failed to discard UNSPEC address address data: %w
- failed to read IPv4 address data: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c35e78e3727e9726.
Report an issue: GitHub.