{"record":{"id":"8cc2e2e7edd225e0","repo":"influxdata/influxdb","slug":"not-poisoned-8cc2e2","errorCode":null,"errorMessage":"not poisoned","messagePattern":"not poisoned","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/object_store_mem_cache/src/cache_system/s3_fifo_cache/s3_fifo.rs","lineNumber":40,"sourceCode":"\n/// Entry within [`S3Fifo`].\n#[derive(Debug)]\npub struct S3FifoEntry<K, V>\nwhere\n    K: ?Sized,\n{\n    key: Arc<K>,\n    value: RwLock<V>,\n    generation: u64,\n    freq: AtomicU8,\n}\n\nimpl<K, V> S3FifoEntry<K, V>\nwhere\n    K: ?Sized,\n{\n    pub(crate) fn value(&self) -> RwLockReadGuard<'_, V> {\n        self.value.read().expect(\"not poisoned\")\n    }\n}\n\nimpl<K, V> HasSize for S3FifoEntry<K, V>\nwhere\n    K: HasSize + ?Sized,\n    V: HasSize,\n{\n    fn size(&self) -> usize {\n        let Self {\n            key,\n            value,\n            generation: _,\n            freq: _,\n        } = self;\n        key.size() + value.read().expect(\"not poisoned\").size()\n    }\n}","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/influxdata/influxdb/blob/d28e26e048401c53cbb98cf2d6ab0cf1e98048ca/core/object_store_mem_cache/src/cache_system/s3_fifo_cache/s3_fifo.rs#L22-L58","documentation":"S3FifoEntry stores its value in a std RwLock; value() takes a read guard with .expect(\"not poisoned\"). The RwLock is poisoned when some thread panicked while holding a WRITE guard on this same entry's value — most commonly a panic inside V::in_use() (which takes self.value.write()) or any internal mutation path. From then on, every read of that entry's value panics with this message.","triggerScenarios":"Cache.get()/read paths on an entry whose value RwLock was poisoned earlier, i.e. after a panic inside a write-lock holder such as in_use() (s3_fifo.rs:69), entry_likely_in_use (s3_fifo.rs:82), or any code mutating the cached value under the write guard.","commonSituations":"A cached value type V whose in_use()/update logic panics once (bad data, index math, unwrap inside V); afterwards every reader of that key panics, turning one bad entry into repeated panics; crates built with panic=abort abort the process at the first write-side panic instead.","solutions":["Find the original panic in the logs — it came from code holding the write side of this entry's lock (typically V::in_use) — and fix V so it cannot panic.","Restart (or evict/re-create the cache) to drop the poisoned entry; a poisoned RwLock never recovers.","Audit custom V implementations for unwraps/expects/indexing that can panic on malformed cached data.","Library-level option: change value() to recover guards via unwrap_or_else(|e| e.into_inner()), accepting possibly-inconsistent V state, or use parking_lot RwLock (no poisoning)."],"exampleFix":"// before\npub(crate) fn value(&self) -> RwLockReadGuard<'_, V> {\n    self.value.read().expect(\"not poisoned\")\n}\n\n// after\npub(crate) fn value(&self) -> RwLockReadGuard<'_, V> {\n    self.value.read().unwrap_or_else(|e| e.into_inner())\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make V::in_use and any value-mutation code panic-free — they hold the write side and are the poison source.","Audit cached value types for unwrap/expect/index/ division that can panic on malformed data.","Run integration tests that force eviction and concurrent reads to surface lock poisoning early.","Consider catch_unwind around request handling that reads cached values, degrading to a cache miss instead of a panic."],"tags":["rust","rwlock","poisoned-lock","s3-fifo-cache","panic"],"backgroundTag":"poisoned-lock","analyzedSha":"d28e26e048401c53cbb98cf2d6ab0cf1e98048ca","analyzedAt":"2026-08-16T19:53:34.623Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}