cloudflare/cloudflared · error

invalid request id length provided

Error message

invalid request id length provided

What it means

ErrInvalidRequestIDLen is returned by RequestIDFromSlice in quic/v3/request.go when the input byte slice is not exactly 16 bytes (datagramRequestIdLen). RequestID is a 128-bit (request-id-v2) identifier used to distinguish proxied flows/sessions between the edge and cloudflared, so it can only be parsed from exactly 16 bytes. The library throws this instead of guessing/truncating to keep request IDs lossless.

Source

Thrown at quic/v3/request.go:15

package v3

import (
	"encoding/binary"
	"errors"
	"fmt"
)

const (
	datagramRequestIdLen = 16
)

var (
	// ErrInvalidRequestIDLen is returned when the provided request id can not be parsed from the provided byte slice.
	ErrInvalidRequestIDLen error = errors.New("invalid request id length provided")
	// ErrInvalidPayloadDestLen is returned when the provided destination byte slice cannot fit the whole request id.
	ErrInvalidPayloadDestLen error = errors.New("invalid payload size provided")
)

// RequestID is the request-id-v2 identifier, it is used to distinguish between specific flows or sessions proxied
// from the edge to cloudflared.
type RequestID uint128

type uint128 struct {
	hi uint64
	lo uint64
}

// RequestIDFromSlice reads a request ID from a byte slice.
func RequestIDFromSlice(data []byte) (RequestID, error) {
	if len(data) != datagramRequestIdLen {
		return RequestID{}, ErrInvalidRequestIDLen
	}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Check len(data) == 16 before calling RequestIDFromSlice and fix the caller that produces a shorter/longer slice.
  2. Strip any datagram header/length prefix so the slice starts exactly at the 16-byte request id.
  3. Verify both sides use the same request-id version (request-id-v2, 16 bytes); upgrade cloudflared/edge consistently.
  4. If handling variable-size payloads, guard with a length check and return a descriptive error instead of panicking on the sentinel.

Example fix

// before
reqID, err := v3.RequestIDFromSlice(payload[:8])
// after
if len(payload) < v3.DatagramRequestIdLen { // or explicitly: len(payload[:16]) == 16
    return fmt.Errorf("datagram too short: %d bytes", len(payload))
}
reqID, err := v3.RequestIDFromSlice(payload[:16])
Defensive patterns

Strategy: validation

Validate before calling

if len(data) != 16 {
    return fmt.Errorf("request id must be 16 bytes, got %d", len(data))
}
reqID, err := v3.RequestIDFromSlice(data)

Type guard

func isFullRequestID(b []byte) bool { return len(b) == 16 }

Try / catch

reqID, err := v3.RequestIDFromSlice(data)
if errors.Is(err, v3.ErrInvalidRequestIDLen) {
    // log payload length, skip or resync datagram framing
    return err
}

Prevention

When it happens

Trigger: Calling v3.RequestIDFromSlice with a slice whose len != 16: e.g. passing a truncated datagram payload, a payload with a header/length prefix not stripped, an empty slice, or a 64-bit request ID produced by an older edge protocol version.

Common situations: Parsing a QUIC datagram that was truncated in transit; mixing cloudflared versions where edge sends request-id-v1 (8-byte) payloads but the local library expects request-id-v2 (16-byte); hand-crafting test payloads of the wrong size; reading a fixed-size record from a stream and miscounting the offset.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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