{"record":{"id":"b2fc8c8ad5b464d4","repo":"vectordotdev/vector","slug":"couldn-t-acquire-lock-on-internal-logs-buffer","errorCode":null,"errorMessage":"Couldn't acquire lock on internal logs buffer","messagePattern":"Couldn't acquire lock on internal logs buffer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/trace.rs","lineNumber":153,"sourceCode":"\n        let rate_limited =\n            RateLimitedLayer::new(formatter).with_default_limit(internal_log_rate_limit);\n        let subscriber = subscriber.with(rate_limited.with_filter(fmt_filter));\n\n        _ = subscriber.try_init();\n    }\n}\n\n#[cfg(test)]\npub fn reset_early_buffer() -> Option<Vec<LogEvent>> {\n    get_early_buffer().replace(Vec::new())\n}\n\n/// Gets a  mutable reference to the early buffer.\nfn get_early_buffer() -> MutexGuard<'static, Option<Vec<LogEvent>>> {\n    BUFFER\n        .lock()\n        .expect(\"Couldn't acquire lock on internal logs buffer\")\n}\n\n/// Determines whether tracing events should be processed (e.g. converted to log\n/// events) to avoid unnecessary performance overhead.\n///\n/// Checks if [`BUFFER`] is set or if a trace sender exists\nfn should_process_tracing_event() -> bool {\n    get_early_buffer().is_some() || maybe_get_trace_sender().is_some()\n}\n\n/// Attempts to buffer an event into the early buffer.\nfn try_buffer_event(log: &LogEvent) -> bool {\n    if SHOULD_BUFFER.load(Ordering::Acquire)\n        && let Some(buffer) = get_early_buffer().as_mut()\n    {\n        buffer.push(log.clone());\n        return true;\n    }","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/trace.rs#L135-L171","documentation":"`get_early_buffer` locks the process-wide static `BUFFER` mutex holding the early internal-log buffer. If the mutex is poisoned (another thread panicked while holding it), `.lock()` returns `Err` and this `expect` panics with \"Couldn't acquire lock on internal logs buffer\". It signals unrecoverable corruption of tracing's internal state.","triggerScenarios":"Any call to `get_early_buffer` (via `reset_early_buffer`, `should_process_tracing_event`, `try_buffer_event`, or `consume_early_buffer`) after a previous panic occurred inside a closure that held the BUFFER lock.","commonSituations":"A panic inside tracing event processing left BUFFER poisoned; subsequent internal trace calls then cascade-panic. Rare in production; usually follows another bug (e.g. a panicking user transform that emits internal log events).","solutions":["Find and fix the original panic that poisoned the BUFFER mutex (it precedes this message in logs)","Restart the process; poisoning is not recoverable at runtime","Avoid panicking in code paths that emit internal tracing events","If reproducible without a root cause, file a Vector issue with a reproducer"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// poisoning is not catchable per-lock; isolate the panic and treat as fatal\nlet guard = std::panic::catch_unwind(|| {\n    // code path that emits internal trace events\n});\nif guard.is_err() { eprintln!(\"trace buffer poisoned; restarting\"); }","preventionTips":["Never panic in code that emits internal log/trace events","Watch logs for earlier panics (root cause precedes this)","Treat mutex-poisoning panics as fatal and restart","Keep internal tracing paths panic-free in forks"],"tags":["rust","panic","mutex-poisoning","tracing"],"backgroundTag":"invalid-state-transition","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}