cloudflare/cloudflared · error

payload length is too small to fit the datagram header

Error message

payload length is too small to fit the datagram header

What it means

ErrDatagramPayloadHeaderTooSmall is returned by MarshalPayloadHeaderTo when the destination buffer is smaller than DatagramPayloadHeaderLen. The function writes the datagram type byte, request ID and payload length fields into the provided slice, so a buffer that cannot hold the header would be overrun. It is a caller-supplied buffer sizing error, wrapped as a marshal error.

Source

Thrown at quic/v3/datagram_errors.go:12

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. Use MarshalBinary() on the datagram struct instead of manually sizing the buffer — it allocates the right size automatically
  2. Allocate payload buffer as len(udpPayload) + DatagramPayloadHeaderLen before calling MarshalPayloadHeaderTo
  3. Add a length assertion or helper that reserves header space before writing payloads

Example fix

// before
payload := makePayload(16) // too small for header
err := v3.MarshalPayloadHeaderTo(testRequestID, payload)
// after
payload := make([]byte, DatagramPayloadHeaderLen+len(udpPayload))
err := v3.MarshalPayloadHeaderTo(testRequestID, payload)
Defensive patterns

Strategy: validation

Validate before calling

if len(buf) < DatagramPayloadHeaderLen {
    buf = make([]byte, DatagramPayloadHeaderLen+len(udpPayload))
}

Try / catch

if err := v3.MarshalPayloadHeaderTo(id, buf); errors.Is(err, v3.ErrDatagramPayloadHeaderTooSmall) {
    return fmt.Errorf("buffer too small for datagram header: need %d bytes", DatagramPayloadHeaderLen)
}

Prevention

When it happens

Trigger: Calling v3.MarshalPayloadHeaderTo(requestID, payload) with len(payload) < DatagramPayloadHeaderLen. In tests this is reproduced with a 16-byte buffer when the required header is longer.

Common situations: Preallocating a buffer from the payload size without accounting for the header bytes; reusing a small scratch buffer; manually building datagram frames instead of letting MarshalBinary allocate the correctly sized buffer.

Related errors


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