cloudflare/cloudflared · warning
failed to parse ICMPv6
Error message
failed to parse ICMPv6
What it means
The IPv6 branch of Decoder.Decode parses the ICMPv6 header+payload with icmp.ParseMessage using the ICMPv6 protocol number. Failure means the bytes following the IPv6 header are not a valid ICMPv6 message; the error is wrapped and Decode fails for this packet.
Source
Thrown at packet/decoder.go:171
if err != nil {
return nil, err
}
msg, err := icmp.ParseMessage(int(layers.IPProtocolICMPv4), append(pd.icmpv4.Contents, pd.icmpv4.Payload...))
if err != nil {
return nil, errors.Wrap(err, "failed to parse ICMPv4 message")
}
return &ICMP{
IP: ipv4,
Message: msg,
}, nil
case layers.LayerTypeICMPv6:
ipv6, err := newIPv6(pd.ipv6)
if err != nil {
return nil, err
}
msg, err := icmp.ParseMessage(int(layers.IPProtocolICMPv6), append(pd.icmpv6.Contents, pd.icmpv6.Payload...))
if err != nil {
return nil, errors.Wrap(err, "failed to parse ICMPv6")
}
return &ICMP{
IP: ipv6,
Message: msg,
}, nil
}
}
layers := make([]string, len(decoded))
for i, l := range decoded {
layers[i] = l.String()
}
return nil, fmt.Errorf("Expect to decode IP and ICMP layers, got %s", layers)
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Inspect the raw IPv6 packet's next-header and payload to confirm it is genuinely ICMPv6.
- Drop the malformed packet and continue; the tunnel proxy can operate without decoding every ICMPv6 datagram.
- Check for truncation in the path delivering packets to the decoder (MTU/fragmentation issues).
- In tests, construct valid ICMPv6 with icmp.ParseMessage-compatible marshaling.
Example fix
// before
if _, err := decoder.Decode(buf); err != nil { return err }
// after
if _, err := decoder.Decode(buf); err != nil {
log.Debug().Err(err).Msg("skipping invalid icmpv6 packet")
return nil
} Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity check before decode: IPv6 (40-byte header) + 8-byte ICMPv6 header
func plausiblyICMPv6(b []byte) bool {
if len(b) < 48 {
return false
}
return b[6] == 58 // next header == ICMPv6
} Try / catch
decoded, err := decoder.Decode(raw)
if err != nil {
log.Debug().Err(err).Msg("dropping undecodable icmpv6 packet")
return nil
} Prevention
- Drop undecodable packets gracefully; the tunnel can keep operating.
- Confirm the packet's next-header actually indicates ICMPv6 before decoding.
- Watch for fragmentation/truncation upstream causing malformed payloads.
When it happens
Trigger: Decode is called on a datagram classified as LayerTypeICMPv6 whose Contents/Payload are truncated, corrupted, or not ICMPv6 (wrong protocol payload inside the IPv6 packet).
Common situations: Corrupt datagrams delivered over the QUIC tunnel, misrouted packets where the payload is actually TCP/UDP rather than ICMPv6, or synthetic test data that is malformed.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to send/receive ICMPv6 echo
- failed to parse ICMPv4 message
- quick tunnel provisioning failed
- funnel not found
- payload length is too large to be bundled in datagram
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/60c8b99dec7898d1.
Report an issue: GitHub.