vectordotdev/vector · error · ChunkedGelfDecoderError::PendingMessagesLimitReached

Pending messages limit of

Error message

Pending messages limit of {pending_messages_limit} reached while processing chunk with message id {message_id} and sequence number {sequence_number}

What it means

The chunked GELF decoder buffers incomplete messages in a pending-messages map so out-of-order UDP chunks can be reassembled. To bound memory, each decoder enforces `pending_messages_limit`; when a new chunk would push the count of pending (incomplete) messages to the limit, decoding fails with this error naming the message id, sequence number, and configured limit. It is a deliberate backpressure/memory-protection mechanism for lossy or flood conditions.

Solutions

  1. Increase `pending_messages_limit` in the source configuration to match the expected concurrency of incomplete messages.
  2. Investigate upstream packet loss or retransmission issues that leave messages permanently incomplete.
  3. Ensure senders chunk messages small enough (few chunks) and send chunks consecutively so they reassemble quickly.
  4. Raise `max_buffered_payload` alongside the limit if messages are large, since both caps interact.

Example fix

# before
sources:
  gelf:
    decoding:
      chunked_gelf:
        pending_messages_limit: 16

# after
sources:
  gelf:
    decoding:
      chunked_gelf:
        pending_messages_limit: 1024
Defensive patterns

Strategy: fallback

Validate before calling

// size your limit against expected concurrency of incomplete messages
let expected_incomplete = avg_messages_per_second * max_reassembly_seconds;
assert!(expected_incomplete < pending_messages_limit,
        "pending_messages_limit too small: raise above {expected_incomplete}");

Try / catch

match framing.decode(&datagram) {
    Err(e) if e.to_string().contains("Pending messages limit") => {
        // back off / shed load rather than retrying immediately
        apply_backoff();
        metrics.incr("gelf_pending_limit_hit");
    }
    other => { /* handle normally */ }
}

Prevention

When it happens

Trigger: decode_chunk receives a chunk whose message id has no pending entry while `pending.messages.len()` is already at `pending_messages_limit` — i.e. many distinct incomplete messages are buffered simultaneously.

Common situations: A high-volume GELF sender with heavy packet loss so most messages never complete reassembly and clog the buffer; a misconfigured (too low) `pending_messages_limit` for the traffic profile; a sender generating huge numbers of unique message ids.

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 vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/b9e4c6d5d3537af0. Report an issue: GitHub.

Appendix: source

Thrown at lib/codecs/src/decoding/framing/chunked_gelf.rs:478

            }
            return Ok(Some(chunk));
        }

        let mut pending = self.state.lock().expect("poisoned lock");

        let is_new_message = !pending.messages.contains_key(&message_id);
        // Settle every admission rule before creating state and a timeout task. The count limit
        // applies only on insert, since rejecting chunks of pending messages would stall them.
        if is_new_message {
            if chunk_len > self.max_length {
                return Err(ChunkedGelfDecoderError::MaxLengthExceed {
                    message_id,
                    sequence_number,
                    length: chunk_len,
                    max_length: self.max_length,
                });
            }
            ensure!(
                pending.messages.len() < self.pending_messages_limit,
                PendingMessagesLimitReachedSnafu {
                    message_id,
                    sequence_number,
                    pending_messages_limit: self.pending_messages_limit
                }
            );
            ensure!(
                pending.buffered_payload.saturating_add(chunk_len) <= self.max_buffered_payload,
                BufferedPayloadLimitReachedSnafu {
                    message_id,
                    sequence_number,
                    limit: self.max_buffered_payload,
                }
            );
        }

        if is_new_message {

View on GitHub (pinned to bdb87aeaa4)