cloudflare/cloudflared · error

datagram icmp payload is missing

Error message

datagram icmp payload is missing

What it means

ErrDatagramICMPPayloadMissing is returned when marshaling or unmarshaling an ICMP datagram that carries no ICMP payload. ICMP datagrams consist of a 1-byte ICMPType header plus a mandatory payload; the library refuses to encode or decode an empty one because such a datagram carries no diagnosable information. Wrapped as a marshal/unmarshal error.

Source

Thrown at quic/v3/datagram_errors.go:19

package v3

import (
	"errors"
	"fmt"
)

var (
	ErrInvalidDatagramType                 error = errors.New("invalid datagram type expected")
	ErrDatagramHeaderTooSmall              error = fmt.Errorf("datagram should have at least %d byte", datagramTypeLen)
	ErrDatagramPayloadTooLarge             error = errors.New("payload length is too large to be bundled in datagram")
	ErrDatagramPayloadHeaderTooSmall       error = errors.New("payload length is too small to fit the datagram header")
	ErrDatagramPayloadInvalidSize          error = errors.New("datagram provided is an invalid size")
	ErrDatagramResponseMsgInvalidSize      error = errors.New("datagram response message is an invalid size")
	ErrDatagramResponseInvalidSize         error = errors.New("datagram response is an invalid size")
	ErrDatagramResponseMsgTooLargeMaximum  error = fmt.Errorf("datagram response error message length exceeds the length of the datagram maximum: %d", maxResponseErrorMessageLen)
	ErrDatagramResponseMsgTooLargeDatagram error = fmt.Errorf("datagram response error message length exceeds the length of the provided datagram")
	ErrDatagramICMPPayloadTooLarge         error = fmt.Errorf("datagram icmp payload exceeds %d bytes", maxICMPPayloadLen)
	ErrDatagramICMPPayloadMissing          error = errors.New("datagram icmp payload is missing")
)

func wrapMarshalErr(err error) error {
	return fmt.Errorf("datagram marshal error: %w", err)
}

func wrapUnmarshalErr(err error) error {
	return fmt.Errorf("datagram unmarshal error: %w", err)
}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Always populate the ICMP payload (original packet or message body) before constructing ICMPDatagram
  2. Validate len(payload) > 0 before calling MarshalBinary/UnmarshalBinary and drop empty ICMP datagrams earlier
  3. Check errors.Is(err, v3.ErrDatagramICMPPayloadMissing) and log the dropped datagram rather than failing the session

Example fix

// before
d := &v3.ICMPDatagram{Payload: []byte{}}
_, err := d.MarshalBinary() // -> ErrDatagramICMPPayloadMissing
// after
if len(rawICMPBody) == 0 {
    return // nothing diagnosable to forward
}
d := &v3.ICMPDatagram{Payload: rawICMPBody}
_, err := d.MarshalBinary()
Defensive patterns

Strategy: validation

Validate before calling

if len(icmpBody) == 0 {
    return // skip constructing ICMP datagram
}

Try / catch

if _, err := d.MarshalBinary(); errors.Is(err, v3.ErrDatagramICMPPayloadMissing) {
    logger.Debug().Msg("ICMP datagram without payload dropped")
    return
}

Prevention

When it happens

Trigger: MarshalBinary on ICMPDatagram with len(d.Payload)==0; UnmarshalBinary on data where only the 1-byte type header is present (len(data[1:])==0).

Common situations: Constructing ICMP error/response datagrams without attaching the original packet bytes or ICMP body; a peer sending a bare type byte; stripping the payload when copying datagrams.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/bea4a7a77cc90d59. Report an issue: GitHub.