vectordotdev/vector · error · ChunkedGelfDecoderError
Received chunk with message id {message_id} and sequence num
Error message
Received chunk with message id {message_id} and sequence number {sequence_number} has an invalid total chunks value of {total_chunks}. It must be between 1 and {GELF_MAX_TOTAL_CHUNKS}. What it means
In a chunked GELF datagram, the byte after the sequence number declares the total number of chunks for the message, and it must be between 1 and GELF_MAX_TOTAL_CHUNKS (128). If the byte is 0 or greater than 128, `InvalidTotalChunksSnafu` rejects the chunk with this message. This guards the reassembly buffer from absurd allocation sizes driven by corrupt or hostile datagrams.
Source
Thrown at lib/codecs/src/decoding/framing/chunked_gelf.rs:352
// | 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!(
sequence_number < total_chunks,
InvalidSequenceNumberSnafu {
message_id,
sequence_number,
total_chunks
}
);
let mut state_lock = self.state.lock().expect("poisoned lock");View on GitHub (pinned to 99894c8d88)
Solutions
- Compare the sender's chunk header layout byte-for-byte against the GELF chunking spec (8-byte id, 1-byte seq, 1-byte total).
- If the sender legitimately needs >128 chunks, split messages further upstream so each message fits in ≤128 chunks.
- Capture one failing datagram with tcpdump and hex-dump the first 10 bytes to confirm which side is wrong.
Defensive patterns
Strategy: try-catch
Try / catch
Err(e) if e.to_string().contains("invalid total chunks value") => {
metrics.counter("gelf_bad_total_chunks", 1);
debug!(error = %e, "discarding datagram with invalid total chunks");
} Prevention
- Unit-test sender chunking against the spec: total in 1..=128, one byte big-endian semantics.
- Alert on the rate of framing errors per source; a spike usually means a bad sender build.
When it happens
Trigger: A datagram with magic `0x1e 0x0f` where the 10th byte (total chunks) is 0 or >128 — e.g. a sender that writes the count as a 16/32-bit integer instead of one byte, or arbitrary binary that collides with the magic bytes.
Common situations: Custom GELF chunker implementations that misplace the header layout; fuzzing/scanners hitting the UDP port; corrupted datagrams from a misbehaving Graylog forwarder.
Related errors
- Invalid chunk header with less than 10 bytes: 0x{header:0x}
- Received chunk with message id {message_id} and sequence num
- Pending messages limit of {pending_messages_limit} reached w
- Received chunk with message id {message_id} and sequence num
- IPv6 multicast is not supported
AI-assisted analysis of vectordotdev/vector@99894c8d88 (2026-08-20).
Data as JSON: /api/errors/294cf9a4100cf4d3.
Report an issue: GitHub.