cloudflare/cloudflared · warning
failed to parse ICMPv4 message
Error message
failed to parse ICMPv4 message
What it means
Decoder.Decode reconstructs ICMPv4 packets: after parsing the IPv4 header, it feeds the concatenated ICMP header+payload bytes to golang.org/x/net/icmp's ParseMessage. If those bytes are not a valid ICMPv4 message, the parse error is wrapped with this message and Decode returns nil error result.
Source
Thrown at packet/decoder.go:158
}
func (pd *ICMPDecoder) Decode(packet RawPacket) (*ICMP, error) {
// Should decode to IP and optionally ICMP layer
decoded, err := pd.decodeByVersion(packet.Data)
if err != nil {
return nil, err
}
for _, layerType := range decoded {
switch layerType {
case layers.LayerTypeICMPv4:
ipv4, err := newIPv4(pd.ipv4)
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,
}, nilView on GitHub (pinned to 2253eeeb25)
Solutions
- Log the raw packet bytes to confirm the ICMPv4 header (type/code/checksum) is complete and well-formed.
- Verify the sender/edge is forwarding full ICMP datagrams without truncation.
- Handle the decode error gracefully (drop the packet) — for a tunnel proxy this usually indicates a corrupt datagram, not a local bug.
- If reproducing in tests, build messages with icmp.Message.Marshal instead of hand-crafted bytes.
Example fix
// before
c, err := decoder.Decode(rawPacket)
if err != nil { return err }
// after
c, err := decoder.Decode(rawPacket)
if err != nil {
log.Debug().Err(err).Msg("dropping malformed icmp packet")
return nil // skip malformed packet
} Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity check before decode: at least an IPv4 header + 8-byte ICMP header
func plausiblyICMPv4(b []byte) bool {
if len(b) < 28 {
return false
}
return b[9] == 1 // protocol == ICMP
} Try / catch
decoded, err := decoder.Decode(raw)
if err != nil {
log.Debug().Err(err).Msg("dropping undecodable packet")
return nil
} Prevention
- Treat decode failures on individual datagrams as non-fatal; drop and continue.
- Verify MTU along the tunnel path to avoid truncated payloads.
- In tests, marshal ICMP messages with x/net/icmp instead of hand-built bytes.
When it happens
Trigger: Calling packet.Decoder.Decode (via handlePacket/handleFullPacket on QUIC/UDP datagrams) with a packet whose ICMPv4 contents/payload are truncated or malformed, so icmp.ParseMessage fails.
Common situations: Corrupted or truncated datagrams from the edge, packets reassembled incorrectly, or tests feeding synthetic bytes that do not form valid ICMPv4 (see TestDecodeBadPackets).
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
- funnel not found
- expect IPv4, but %s is IPv6
- expect IPv6, but %s is IPv4
- failed to determine IPv4 source address for ICMP proxy
- failed to determine IPv6 source address for ICMP proxy
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/f9ce4db493057463.
Report an issue: GitHub.