nats-io/nats-server · error
%w: v1 line too long
Error message
%w: v1 line too long
What it means
The server detected that the PROXY protocol v1 header line exceeded the protocol maximum of 107 bytes (including CRLF) without encountering a terminating CRLF. Per the PROXY protocol spec, a v1 header must fit in 107 bytes, so a longer line means the sender is not a conforming proxy or the stream is corrupted. The server aborts the connection with an error wrapping errProxyProtoInvalid.
Source
Thrown at server/client_proxyproto.go:168
if err != nil {
return nil, nil, fmt.Errorf("failed to read v1 line: %w", err)
}
line = buf[:len(line)+n]
// Look for CRLF in what we've read so far
for i := 0; i < len(line)-1; i++ {
if line[i] == '\r' && line[i+1] == '\n' {
// Found CRLF - keep any over-read bytes for the client parser.
remaining = append(remaining, line[i+2:]...)
line = line[:i]
goto foundCRLF
}
}
}
// Exceeded max length without finding CRLF
return nil, nil, fmt.Errorf("%w: v1 line too long", errProxyProtoInvalid)
foundCRLF:
// Get parts from the protocol
parts := strings.Fields(string(line))
// Validate format
if len(parts) < 1 {
return nil, nil, fmt.Errorf("%w: invalid v1 format", errProxyProtoInvalid)
}
// Handle UNKNOWN (health check, like v2 LOCAL)
if parts[0] == proxyProtoV1Unknown {
return nil, remaining, nil
}
// Must have exactly 5 parts: protocol, src-ip, dst-ip, src-port, dst-port
if len(parts) != 5 {
return nil, nil, fmt.Errorf("%w: invalid v1 format", errProxyProtoInvalid)View on GitHub (pinned to 3a66a489d2)
Solutions
- Verify the upstream proxy actually emits conforming PROXY v1 headers (max 107 bytes ending in CRLF)
- Check the load balancer's proxy-protocol configuration (e.g. HAProxy 'send-proxy' vs 'send-proxy-v2') and fix version mismatch
- Ensure no non-PROXY-protocol clients are connecting directly to the proxy-protocol port
- Capture the incoming bytes with tcpdump/ngrep to identify the offending sender
Example fix
// before: proxy sends oversized header PROXY TCP4 2001:0db8:85a3:0000:0000:8a2e:0370:7334-with-garbage-padding... (no CRLF within 107 bytes) // after: proxy emits conforming header PROXY TCP4 192.0.2.1 198.51.100.7 35646 4222\r\n
Defensive patterns
Strategy: validation
Validate before calling
// Before emitting a PROXY v1 header from your proxy/client:
header := fmt.Sprintf("PROXY %s %s %s %d %d\r\n", proto, srcIP, dstIP, srcPort, dstPort)
if len(header) > 107 {
return errors.New("PROXY v1 header exceeds 107-byte limit")
}
conn.Write([]byte(header)) Type guard
func isValidV1HeaderLine(line string) bool {
return len(line) <= 107 && strings.HasSuffix(line, "\r\n")
} Try / catch
addr, _, err := readProxyProtoHeader(conn)
if err != nil {
if errors.Is(err, errProxyProtoInvalid) {
log.Printf("malformed PROXY header (line too long): %v", err)
conn.Close() // drop non-conforming sender
return
}
return err
} Prevention
- Keep v1 headers under 107 bytes including CRLF
- Use PROXY v2 (binary, fixed signature) for dual-stack setups to avoid length edge cases
- Monitor server logs for 'v1 line too long' to catch misbehaving senders early
- Never point raw clients at a PROXY-protocol listener
When it happens
Trigger: A client connects to a PROXY-protocol-enabled listener and sends 'PROXY ' followed by more than 101 additional bytes (107 - 6 already read) without a '\r\n' terminator; e.g. a non-proxy client sending arbitrary text, or a proxy emitting a malformed over-long header.
Common situations: Misconfigured load balancer (HAProxy/nginx) sending non-standard headers; a plain NATS client accidentally pointed at a proxy-protocol port; a health-check or port scanner writing long garbage lines; corrupted TCP stream from a broken intermediary.
Related errors
- failed to read protocol version: %w
- failed to read v1 line: %w
- %w: invalid v1 format
- %w: invalid address
- invalid source port: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/eea88d47e3a2b6ce.
Report an issue: GitHub.