vectordotdev/vector · error
linger should exists for poll_flush
Error message
linger should exists for poll_flush
What it means
This panic fires in the partition batch sink's `poll_flush` when `lingers.get_mut(partition)` returns `None` for a partition that has an active batch. The sink maintains `partitions` and `lingers` maps in lockstep (every batched partition gets a linger timer), so a missing linger is an internal state inconsistency.
Solutions
- Report as a bug to Vector with the sink type and scenario.
- Check for recent patches to the partition batch sink that alter partitions/lingers bookkeeping.
- Restart the topology to clear inconsistent in-memory state and confirm reproducibility.
Defensive patterns
Strategy: fallback
Prevention
- Keep partitions and lingers insertion/removal in lockstep when patching sink.rs.
- Restart the topology to clear inconsistent state after upgrades.
- Report reproducible occurrences with the sink type and config.
When it happens
Trigger: Polling flush on a partitioned sink where the `partitions` map contains a key absent from `lingers` — e.g. a logic bug that inserts a batch without a corresponding linger, or removes a linger without removing the batch.
Common situations: Not reachable via configuration; appears only from bugs in partition lifecycle code or custom patches to src/sinks/util/sink.rs.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- a record with a next ID must have an event count
- a valid HTTP/1 URI is valid as an HTTP URI
- a validated HTTP endpoint is a valid `http 1` URI
- all json-file keys should be matched
- allowed_lateness_ms validated to fit in i64 in…
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/3ff25f364ca93a27.
Report an issue: GitHub.
Appendix: source
Thrown at src/sinks/util/sink.rs:298
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
loop {
// Poll inner service while not ready, if we don't have buffer or any batch.
if self.buffer.is_none() && self.partitions.is_empty() {
ready!(self.service.poll_complete(cx));
return Poll::Ready(Ok(()));
}
// Try send batches.
let this = self.as_mut().project();
let mut partitions_ready = vec![];
for (partition, batch) in this.partitions.iter() {
if ((*this.closing && !batch.is_empty())
|| batch.was_full()
|| matches!(
this.lingers
.get_mut(partition)
.expect("linger should exists for poll_flush")
.poll_unpin(cx),
Poll::Ready(())
))
&& this
.in_flight
.as_mut()
.and_then(|map| map.get_mut(partition))
.map(|req| matches!(req.poll_unpin(cx), Poll::Ready(())))
.unwrap_or(true)
{
partitions_ready.push(partition.clone());
}
}
let mut batch_consumed = false;
for partition in partitions_ready.iter() {
let service_ready = match this.service.poll_ready(cx) {
Poll::Ready(Ok(())) => true,
Poll::Ready(Err(error)) => return Poll::Ready(Err(error)),View on GitHub (pinned to bdb87aeaa4)