dbt-labs/dbt-core · error
inconsistent park_timeout state: {n}
Error message
inconsistent park_timeout state: {n} What it means
This panic is a defensive invariant check in the thread parking primitive used by dbt-runtime. The parker's state machine has exactly three legal values (EMPTY, PARKED, NOTIFIED); after a timed wait, the atomic state is swapped back to EMPTY, and any value other than NOTIFIED or PARKED means the state machine was corrupted, so the library aborts rather than continue in an undefined synchronization state.
Source
Thrown at crates/dbt-runtime/src/park.rs:163
// We must read again here, see `park`.
let old = self.state.swap(EMPTY, SeqCst);
debug_assert_eq!(old, NOTIFIED, "park state changed unexpectedly");
return;
}
Err(actual) => panic!("inconsistent park_timeout state; actual = {actual}"),
}
// Wait with a timeout, and if we spuriously wake up or otherwise wake up
// from a notification, we just want to unconditionally set the state back to
// empty, either consuming a notification or un-flagging ourselves as
// parked.
let (_m, _result) = self.condvar.wait_timeout(m, dur).unwrap();
match self.state.swap(EMPTY, SeqCst) {
NOTIFIED => {} // got a notification, hurray!
PARKED => {} // no notification, alas
n => panic!("inconsistent park_timeout state: {n}"),
}
}
fn unpark(&self) {
// To ensure the unparked thread will observe any writes we made before
// this call, we must perform a release operation that `park` can
// synchronize with. To do that we must write `NOTIFIED` even if `state`
// is already `NOTIFIED`. That is why this must be a swap rather than a
// compare-and-swap that returns if it reads `NOTIFIED` on failure.
match self.state.swap(NOTIFIED, SeqCst) {
EMPTY => return, // no one was waiting
NOTIFIED => return, // already unparked
PARKED => {} // gotta go wake someone up
_ => panic!("inconsistent state in unpark"),
}
// There is a period between when the parked thread sets `state` to
// `PARKED` (or last checked `state` in the case of a spurious wakeView on GitHub (pinned to 0267ce9170)
Solutions
- Report the issue to the dbt-runtime maintainers with a minimal reproducer; this indicates a bug in the parker's internal state machine
- Check for unsafe code in your project that aliases or writes to the parker's internal state
- Update dbt-runtime to the latest version in case the invariant bug is already fixed
- Capture the panicking state value ({n} in the message) and add debug assertions around park/unpark call sites in your code
Defensive patterns
Strategy: try-catch
Try / catch
// park_timeout is an internal primitive; if surfaced, catch panic and report
let result = std::panic::catch_unwind(|| parker.park_timeout(dur));
if result.is_err() { /* log state-machine corruption and file a bug */ } Prevention
- Do not write to the parker's internal state from unsafe code
- Keep dbt-runtime updated
- Run concurrency tests under Miri/ThreadSanitizer
- Report any occurrence with a reproducer — it is always a bug
When it happens
Trigger: park_timeout observes an atomic state value outside the {EMPTY, PARKED, NOTIFIED} domain when re-reading state after condvar.wait_timeout returns — i.e. memory corruption or a misuse of the parker internals writes an out-of-domain value into self.state.
Common situations: Practically unreachable for library users; seen only during fuzzing, unsafe-code misuse around the parker, or a bug in dbt-runtime itself. Developers encounter it while debugging concurrency bugs or after low-memory/alien-thread interference in custom runtime extensions.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- inconsistent state in unpark
- inconsistent park state; actual = {actual}
- inconsistent park_timeout state; actual = {actual}
- failed to generate unique thread ID: bitspace exhausted
- waker missing
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/505034cfa7e1ca3a.
Report an issue: GitHub.