cloudflare/cloudflared · error

payload length is too large to be bundled in datagram

Error message

payload length is too large to be bundled in datagram

What it means

ErrDatagramPayloadTooLarge is returned when marshaling a datagram whose payload exceeds the maximum allowed size for the datagram's destination IP family. The library enforces a hard payload limit (maxPayloadLen) because QUIC datagrams must fit within a single QUIC packet and MTU constraints. MarshalBinary checks the payload length before allocating the buffer and fails fast with this sentinel error (wrapped by wrapMarshalErr).

Source

Thrown at quic/v3/datagram_errors.go:11

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. Check the payload length against the library's maxPayloadLen budget before constructing the datagram and reject or truncate oversized payloads upstream
  2. Return an ICMP 'packet too big' style response to the origin so it lowers its path MTU and retransmits a smaller packet
  3. Keep per-protocol payload caps aligned with QUIC/UDP MTU guidance (e.g. ~1200-1500 bytes minus datagram header overhead)
  4. Use errors.Is(err, v3.ErrDatagramPayloadTooLarge) to branch and drop/log the datagram instead of tearing down the session

Example fix

// before
payload := make([]byte, 2000) // exceeds maxPayloadLen
datagram := &v3.UDPSessionPayloadDatagram{RequestID: id, Payload: payload}
_, err := datagram.MarshalBinary() // -> ErrDatagramPayloadTooLarge
// after
const maxUDPPayload = 1280 // safe budget for datagram framing
if len(payload) > maxUDPPayload {
    // respond ICMP type 3 code 4 'fragmentation needed' or drop
    return
}
datagram := &v3.UDPSessionPayloadDatagram{RequestID: id, Payload: payload}
_, err := datagram.MarshalBinary()
Defensive patterns

Strategy: validation

Validate before calling

if len(payload) > maxUDPPayloadLen { // query from library or use a safe MTU-derived budget
    // drop or emit ICMP fragmentation-needed
    return
}

Try / catch

if _, err := d.MarshalBinary(); errors.Is(err, v3.ErrDatagramPayloadTooLarge) {
    logger.Warn().Int("len", len(d.Payload)).Msg("datagram payload too large, dropped")
    return
}

Prevention

When it happens

Trigger: Calling UDPSessionPayloadDatagram.MarshalBinary() with a Payload slice longer than maxPayloadLen (the size budget for the destination IP family). Typically happens when the caller passes an application UDP payload larger than the QUIC datagram frame can carry.

Common situations: Proxying an oversized UDP packet received from the origin (e.g. DNS responses over 1232 bytes, large UDP-based protocols like some QUIC/TFTP traffic); misconfigured MTU assumptions; using an IPv4-family size budget while actually sending over IPv6 or vice versa.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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