cloudflare/cloudflared · error

invalid length slice provided to unmarshal: %d (expected 16)

Error message

invalid length slice provided to unmarshal: %d (expected 16)

What it means

RequestID.UnmarshalBinary requires exactly a 16-byte slice, since a RequestID is two big-endian uint64s (high/low). If the input slice is any other length, it returns this error rather than reading out of bounds. It is a strict format check to guarantee round-trip fidelity with MarshalBinary.

Source

Thrown at quic/v3/request.go:81

	return 0
}

// Less reports whether id sorts before id2.
func (id RequestID) Less(id2 RequestID) bool { return id.Compare(id2) == -1 }

// MarshalBinaryTo writes the id to the provided destination byte slice; the byte slice must be of at least size 16.
func (id RequestID) MarshalBinaryTo(data []byte) error {
	if len(data) < datagramRequestIdLen {
		return ErrInvalidPayloadDestLen
	}
	binary.BigEndian.PutUint64(data[:8], id.hi)
	binary.BigEndian.PutUint64(data[8:], id.lo)
	return nil
}

func (id *RequestID) UnmarshalBinary(data []byte) error {
	if len(data) != 16 {
		return fmt.Errorf("invalid length slice provided to unmarshal: %d (expected 16)", len(data))
	}

	*id = RequestID{
		binary.BigEndian.Uint64(data[:8]),
		binary.BigEndian.Uint64(data[8:]),
	}
	return nil
}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Ensure the input slice is exactly 16 bytes before calling UnmarshalBinary.
  2. Slice the source buffer with data[offset:offset+16] using correct offsets.
  3. Check that the producer serialized with RequestID.MarshalBinary (32 hex/16 bytes) and the payload wasn't truncated in transit.
  4. In tests, use the output of MarshalBinary directly as the UnmarshalBinary input.

Example fix

// before
id.UnmarshalBinary(data[:10])
// after
if len(data) < 16 {
    return fmt.Errorf("need 16 bytes, got %d", len(data))
}
err := id.UnmarshalBinary(data[:16])
Defensive patterns

Strategy: validation

Validate before calling

if len(data) != 16 { return fmt.Errorf("expected 16 bytes for RequestID, got %d", len(data)) }

Type guard

func validRequestID(data []byte) bool { return len(data) == 16 }

Try / catch

if err := id.UnmarshalBinary(data); err != nil {
    return fmt.Errorf("corrupt request id: %w", err)
}

Prevention

When it happens

Trigger: Calling (*RequestID).UnmarshalBinary with a slice whose len != 16, e.g. after slicing a buffer incorrectly or decoding a truncated identifier.

Common situations: Decoding request IDs from truncated datagram payloads; off-by-one slicing of a larger buffer; passing an empty slice to reuse a RequestID variable.

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/26f64533086cc019. Report an issue: GitHub.