vectordotdev/vector · error · ChunkedGelfDecoderError::InvalidChunkHeader
Invalid chunk header with less than 10 bytes: 0x
Error message
Invalid chunk header with less than 10 bytes: 0x{header:0x} What it means
The GELF chunked framing decoder needs at least 10 bytes per chunk: an 8-byte message id, a 1-byte sequence number, and a 1-byte total-chunks count. If a received datagram has fewer than 10 remaining bytes, `decode_chunk` rejects it via `InvalidChunkHeaderSnafu` including the chunk contents in hex. This guards the subsequent `get_u64`/`get_u8` reads from underflowing the buffer.
Solutions
- Verify the sender chunks messages per the GELF spec (chunk only when payload exceeds the chunk size) — a sub-10-byte datagram is not a valid chunk header.
- If messages are meant to be unchunked, reconfigure the source to use plain GELF framing instead of chunked GELF.
- Capture packets (tcpdump/Wireshark) to identify the source of truncated or non-GELF datagrams and fix the upstream client.
- Check network path for MTU/fragmentation issues that could truncate UDP payloads.
Example fix
# before: sender always chunks even tiny messages
send_udp(gelf_bytes) # 8 bytes -> error
# after: only chunk large messages
if gelf_bytes.len() > CHUNK_SIZE { send_chunked(gelf_bytes) } else { send_udp(gelf_bytes) } Defensive patterns
Strategy: validation
Validate before calling
// sender-side guard: only chunk messages that exceed the chunk size
if payload.len() < 10 || payload.len() <= CHUNK_SIZE {
// do not use chunked framing for tiny/unchunked messages
send_unchunked(payload);
} Try / catch
match framing.decode(&datagram) {
Err(e) if e.to_string().contains("Invalid chunk header") => {
warn!("dropping non-chunked/truncated GELF datagram ({} bytes)", datagram.len());
}
other => { /* handle normally */ }
} Prevention
- Verify senders follow the GELF chunking spec: never emit chunks smaller than the 10-byte header.
- Only enable chunked GELF framing for senders that actually chunk their messages.
- Monitor for UDP truncation/corruption with packet captures when this error appears in production.
When it happens
Trigger: A UDP datagram passed to decode_message/decode_chunk contains fewer than 10 bytes — e.g. a truncated packet, a GELF message sent unchunked but routed to the chunked decoder, or a corrupted/empty datagram.
Common situations: A sender emitting small GELF payloads without chunking them (GELF spec says messages under ~8KB should not be chunked) while the source is configured with chunked GELF framing; MTU truncation or packet corruption on the network; a non-GELF sender hitting the GELF UDP port.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Received chunk with message id
- Received chunk with message id
- Buffered payload limit of
- Pending messages limit of
- Received chunk with message id
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/0fd14e916d2ed0bc.
Report an issue: GitHub.
Appendix: source
Thrown at lib/codecs/src/decoding/framing/chunked_gelf.rs:409
pub fn decode_chunk(
&mut self,
mut chunk: Bytes,
) -> Result<Option<Bytes>, ChunkedGelfDecoderError> {
// Encoding scheme:
//
// +------------+-----------------+--------------+----------------------+
// | Message id | Sequence number | Total chunks | Chunk payload |
// +------------+-----------------+--------------+----------------------+
// | 64 bits | 8 bits | 8 bits | remaining bits |
// +------------+-----------------+--------------+----------------------+
//
// As this codec is oriented for UDP, the chunks (datagrams) are not guaranteed to be received in order,
// nor to be received at all. So, we have to store the chunks in a buffer (state field) until we receive
// all the chunks of a message. When we receive all the chunks of a message, we can concatenate them
// and return the complete payload.
// We need 10 bytes to read the message id, sequence number and total chunks
ensure!(
chunk.remaining() >= 10,
InvalidChunkHeaderSnafu { header: chunk }
);
let message_id = chunk.get_u64();
let sequence_number = chunk.get_u8();
let total_chunks = chunk.get_u8();
ensure!(
total_chunks > 0 && total_chunks <= GELF_MAX_TOTAL_CHUNKS,
InvalidTotalChunksSnafu {
message_id,
sequence_number,
total_chunks
}
);
ensure!(View on GitHub (pinned to bdb87aeaa4)