quickwit-oss/quickwit · error
stdin cannot be checkpointed
Error message
stdin cannot be checkpointed
What it means
ByteRangeCacheDirectory (the shared factory) keeps a Mutex-protected map of per-path FileByteRangeCaches. get_file_cache locks that map and `.expect`s the result. The panic occurs only when the map's mutex is poisoned — a thread previously panicked while holding this lock. The tests calling this helper would surface such a poisoning as a hard failure.
Source
Thrown at quickwit/quickwit-metastore/src/metastore/mod.rs:1516
end: Bound::Unbounded,
}
}
}
/// Maps the given source params to whether checkpoints should be stored in the index metadata
/// (false) or the shard table (true)
fn use_shard_api(params: &SourceParams) -> bool {
match params {
SourceParams::File(FileSourceParams::Filepath(_)) => false,
SourceParams::File(FileSourceParams::Notifications(_)) => true,
SourceParams::Ingest => true,
SourceParams::IngestApi => false,
SourceParams::IngestCli => false,
SourceParams::Kafka(_) => false,
SourceParams::Kinesis(_) => false,
SourceParams::PubSub(_) => false,
SourceParams::Pulsar(_) => false,
SourceParams::Stdin => panic!("stdin cannot be checkpointed"),
SourceParams::Vec(_) => false,
SourceParams::Void(_) => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_filter_contains() {
let filter = FilterRange {
start: Bound::Unbounded,
end: Bound::Excluded(50),
};
assert!(!filter.contains(&50));
assert!(filter.contains(&0));
assert!(filter.contains(&49));View on GitHub (pinned to a39730c5cd)
Solutions
- Find the initial panic that poisoned the map (first occurrence in the logs) and fix that bug.
- Restart the process; poisoned mutexes never recover within a process.
- Report with a backtrace of the original panic — panicking while constructing/inserting a file cache is a bug.
- As a defensive code change, use `unwrap_or_else(|poisoned| poisoned.into_inner())` since map entries are individually consistent.
Example fix
// before
let mut file_caches = self
.inner_arc
.file_caches
.lock()
.expect("byte range cache mutex is poisoned");
// after
let mut file_caches = self
.inner_arc
.file_caches
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner()); Defensive patterns
Strategy: retry
Try / catch
// in tests: assert no panic occurred before asserting map behavior let result = std::panic::catch_unwind(|| shared_cache.get_file_cache(path)); assert!(result.is_ok(), "file_caches mutex was poisoned by an earlier panic");
Prevention
- Keep FileByteRangeCache construction panic-free (no expect/assert inside the locked region).
- Run cache tests with panic=abort to surface the original poisoning panic first.
- In shared/global caches, prefer recover_from_poison (into_inner) semantics.
- Alert on any panic in the storage cache module — all later panics are cascade effects.
When it happens
Trigger: A thread panicking while holding the `file_caches` map lock (e.g. during FileByteRangeCache construction in an earlier get_file_cache call or a panic in map insertion), then any subsequent get_file_cache call — in production code or in tests like test_byte_range_cache_is_shared_for_same_path — panics.
Common situations: A bug during cache creation for one path poisons the map; all later storages built on the same shared cache instance then fail; typically observed as a cascade of identical panics across threads.
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
- `append_records` should be called with `position_opt: None`
- failed to run mrecordlog operation
- Unexpected span kind: {}
- missing file `{}` in split bundle
- lock should not be poisoned
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/6ccb2e52eb43e28c.
Report an issue: GitHub.