cloudflare/cloudflared · error
%v is not valid IP
Error message
%v is not valid IP
What it means
registerUdpSession read the destination IP bytes from the RegisterUdpSession RPC parameters and net.IP(dstIPRaw) came back nil, meaning the bytes are not a valid 4- or 16-byte IP representation. cloudflared cannot route a UDP session without a valid destination address, so it rejects the registration.
Source
Thrown at tunnelrpc/pogs/session_manager.go:57
func (i SessionManager_PogsImpl) registerUdpSession(p proto.SessionManager_registerUdpSession) error {
server.Ack(p.Options)
sessionIDRaw, err := p.Params.SessionId()
if err != nil {
return err
}
sessionID, err := uuid.FromBytes(sessionIDRaw)
if err != nil {
return err
}
dstIPRaw, err := p.Params.DstIp()
if err != nil {
return err
}
dstIP := net.IP(dstIPRaw)
if dstIP == nil {
return fmt.Errorf("%v is not valid IP", dstIPRaw)
}
dstPort := p.Params.DstPort()
closeIdleAfterHint := time.Duration(p.Params.CloseAfterIdleHint())
traceContext, err := p.Params.TraceContext()
if err != nil {
return err
}
resp, registrationErr := i.impl.RegisterUdpSession(p.Ctx, sessionID, dstIP, dstPort, closeIdleAfterHint, traceContext)
if registrationErr != nil {
// Make sure to assign a response even if one is not returned from register
if resp == nil {
resp = &RegisterUdpSessionResponse{}
}
resp.Err = registrationErr
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Fix the caller to send a valid dst IP (net.ParseIP(...).To4()/.To16()) in RegisterUdpSessionParams.
- Update cloudflared on both ends to matching versions to avoid payload skew.
- Validate the destination before dialing (net.ParseIP on the configured host).
Example fix
// before
params := quicpogs.RegisterUdpSessionParams{DstIp: []byte("invalid")}
// after
ip := net.ParseIP("198.51.100.7")
params := quicpogs.RegisterUdpSessionParams{DstIp: ip.To4()} Defensive patterns
Strategy: validation
Validate before calling
ip := net.ParseIP(host)
if ip == nil {
return fmt.Errorf("destination %q is not a valid IP", host)
}
params.DstIp = ip.To4()
if params.DstIp == nil { params.DstIp = ip.To16() } Type guard
func isValidDstIP(raw []byte) bool {
return net.IP(raw) != nil && (len(raw) == 4 || len(raw) == 16)
} Prevention
- Always run destinations through net.ParseIP before populating RegisterUdpSessionParams
- Use ip.To4()/To16() to get canonical byte slices
- Keep client and server cloudflared versions aligned
When it happens
Trigger: A RegisterUdpSession RPC arrives whose Params carry a DstIp byte slice that is empty, wrong length, or malformed — i.e., not parseable as an IPv4/IPv6 address.
Common situations: Client-side bug sending uninitialized/garbage IP bytes; QUIC packet marshalled by an incompatible cloudflared version; corrupted RPC payload over the wire.
Related errors
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/7bc85168846818b0.
Report an issue: GitHub.