databendlabs/databend · error
Hash Table is finished
Error message
Hash Table is finished
What it means
In the probe transform's wait_build, the hash table status is checked; HashTableType::UnFinished inside a branch that only runs after the build has finished is asserted to be impossible, so it panics with 'Hash Table is finished'. Hitting it means the probe observed a table state inconsistent with the barrier/synchronization that should guarantee the build completed — an internal synchronization invariant violation.
Solutions
- Check whether the build phase aborted or errored before finalize_done updated the table type; surface that original error instead of panicking
- Verify the status transition to Finished happens under the same synchronization that unblocks waiters
- Add the actual HashTableType value to the panic message for diagnosis
- If triggered by an aborted build, ensure probes observe the failure and return AbortedQuery rather than waiting
Example fix
// before
HashTableType::UnFinished => {
unreachable!("Hash Table is finished")
}
// after
HashTableType::UnFinished => Err(ErrorCode::AbortedQuery(
"Aborted query, because the hash table build did not finish",
)), Defensive patterns
Strategy: try-catch
Validate before calling
// Before waiting, confirm the build will finalize or abort cleanly
if build_aborted.load(Ordering::Acquire) {
return Err(ErrorCode::AbortedQuery("hash table build aborted"));
} Type guard
fn build_finished(t: &HashTableType) -> bool {
!matches!(t, HashTableType::UnFinished)
} Try / catch
match wait_build_result {
Err(e) if e.code() == ErrorCode::ABORTED_QUERY => { log::warn!("build aborted: {}", e); propagate_abort(); }
other => other,
} Prevention
- Ensure build failures/aborts always update the shared table status before unblocking probes
- Use the barrier/finalize_done path consistently; never leave UnFinished reachable after waiters wake
- Keep build and probe on identical versions in distributed deployments
When it happens
Trigger: wait_build proceeds after deciding the build is done, but the shared table type still reports UnFinished; caused by a race between build finalization and probe reads, or incorrect status updates in finalize_done.
Common situations: Distributed/multi-threaded builds where barriers fail or partial builds abort; hangs or errors during build (e.g. aborted query) leaving the status stale; regressions in build-probe synchronization code.
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
- _ => unreachable!()
- HashJoinHashTable::NestedLoop(_) => unreachable!()
- HashJoinHashTable::NestedLoop(_) => unreachable!()
- _ => unreachable!()
- _ => unreachable!()
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/7aa2e38721fa18fe.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/pipelines/processors/transforms/hash_join/transform_hash_join_probe.rs:294
}
self.next_round()
}
fn wait_build(&mut self) -> Result<Event> {
if self.is_build_finished() {
match self.hash_table_type {
HashTableType::FirstRound => self.probe(),
HashTableType::Restored => self.next_step(Step::Async(AsyncStep::Restore)),
HashTableType::Empty => {
if self.can_fast_return() {
self.next_step(Step::Finish)
} else {
self.probe()
}
}
HashTableType::UnFinished => {
unreachable!("Hash Table is finished")
}
}
} else {
self.next_step(Step::Async(AsyncStep::WaitBuild))
}
}
}
#[async_trait::async_trait]
impl Processor for TransformHashJoinProbe {
fn name(&self) -> String {
"HashJoinProbe".to_string()
}
fn as_any(&mut self) -> &mut dyn Any {
self
}
View on GitHub (pinned to 288d84d76e)