risingwavelabs/risingwave · critical
job {} in database {} has tables with different table ids. {
Error message
job {} in database {} has tables with different table ids. {}:{}, {}:{} What it means
validate_database_info requires all state tables of a streaming job to share the same committed epoch, ensuring the job's tables are consistent at a single recovery point. If a table's epoch differs from the first table's epoch, recovery aborts with this error listing both (table, epoch) pairs. Note: the message says 'different table ids' but the values compared are epochs — a message wording quirk.
Source
Thrown at src/meta/src/barrier/mod.rs:209
let mut committed_epochs =
InflightFragmentInfo::existing_table_ids(fragments.values()).map(|table_id| {
(
table_id,
*state_table_committed_epochs
.get(&table_id)
.expect("checked exist"),
)
});
let (first_table, first_epoch) = committed_epochs.next().ok_or_else(|| {
anyhow!(
"job {} in database {} has no state table after recovery",
job_id,
database_id
)
})?;
for (table_id, epoch) in committed_epochs {
if epoch != first_epoch {
return Err(anyhow!(
"job {} in database {} has tables with different table ids. {}:{}, {}:{}",
job_id,
database_id,
first_table,
first_epoch,
table_id,
epoch
)
.into());
}
}
}
}
Ok(())
}
}
#[derive(Debug)]View on GitHub (pinned to 6469eb736d)
Solutions
- Retry recovery from a consistent Hummock version snapshot where all tables share one epoch
- Investigate barrier commit logs to find where table epochs diverged and repair metadata
- Rebuild the affected job (recreate the MV/sink) if its table epochs cannot be reconciled
- File a bug; cross-table epoch atomicity should be guaranteed by barrier commits
Defensive patterns
Strategy: try-catch
Validate before calling
let epochs: HashSet<_> = job.state_tables()
.map(|(t, e)| e)
.collect();
if epochs.len() > 1 { return Err("state tables at divergent epochs; recovery would be inconsistent"); } Try / catch
match validate_database_info(...) {
Err(e) if e.to_string().contains("different table ids") => {
restore_consistent_hummock_snapshot().await; // roll back to a single-epoch version
retry_recovery().await;
}
r => r,
} Prevention
- Commit all state tables of a job atomically within one barrier
- Never restore partial Hummock version checkpoints
- Add cross-table epoch consistency assertions in barrier commit tests
When it happens
Trigger: Recovery where job state tables were committed at different epochs — e.g. some tables advanced in a barrier while others did not, indicating a partially-committed barrier or inconsistent Hummock version pinning.
Common situations: Crash/failover mid-barrier leaving tables at divergent epochs; bugs in barrier commit atomicity across state tables; restored version checkpoints that are partially applied.
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
- inconsistent hummock version: expected {}, actual {}
- worker_id {} for actor {} does not exist
- state table {} is not registered to hummock
- job {} in database {} has no state table after recovery
- since_timestamp requires at least one upstream table
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/3012df457112633d.
Report an issue: GitHub.