influxdata/influxdb · error · TableIndexError
Cannot merge table indices with mismatched identifiers
Error message
Cannot merge table indices with mismatched identifiers: {expected} != {actual} What it means
TableIndexError::MergeMismatch is raised when merging two table indices whose TableIndexId (database/table identifiers plus node identity) do not match. Index merge logic assumes both inputs describe the same table index; a mismatch would silently corrupt the merged index, so it is rejected eagerly. This is an invariant violation rather than an I/O failure.
Solutions
- Log the expected and actual TableIndexId from the error fields to identify which object is mismatched.
- Verify the index is loaded/parsed from the correct object store path for that (db_id, table_id).
- Clear the corrupted/stale index object from the store and rebuild it from snapshots.
- Audit code that constructs or deserializes TableIndexId to ensure it comes from the same source as the index being merged.
Example fix
// before let merged = local_index.merge(loaded_index); // may panic/err at runtime // after assert_eq!(local_index.id(), loaded_index.id(), "refusing to merge indices for different tables"); let merged = local_index.merge(loaded_index);
Defensive patterns
Strategy: validation
Validate before calling
fn can_merge(expected: &TableIndexId, actual: &TableIndexId) -> bool { expected == actual }
// call before merging; if false, skip or rebuild the index instead of merging Try / catch
match result {
Err(TableIndexError::MergeMismatch { expected, actual }) => {
error!(?expected, ?actual, "index id mismatch; rebuilding index from snapshots");
rebuild_index_from_snapshots().await
}
other => other,
} Prevention
- Always load the index from the object store path derived from the same (db_id, table_id).
- Never cache indices across databases/tables in shared maps without keying by TableIndexId.
- After failover/restore, verify node identifiers match before merging persisted indices.
- Add assertions comparing TableIndexId at merge call sites during development.
When it happens
Trigger: Calling the merge operation (e.g. merging a loaded persisted index with a locally built one during update) where expected != actual TableIndexId — typically when a snapshot/index file belongs to a different database or table than the in-memory index being updated.
Common situations: Reusing or mis-pointing index cache paths across databases/tables; restoring an index snapshot into the wrong database; concurrency bugs where two tables' updates interleave; node identifier changes after failover with stale files.
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
- ' ' is a reserved column
- auto field family exists
- By the point that we're doing partitioning, we should've…
- cache error
- can only accept once
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/62824d20698319de.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_write/src/table_index.rs:49
#[error("Failed to list table index snapshots from object store")]
ListSnapshots(#[source] object_store::Error),
#[error("Failed to list table indices from object store")]
ListIndices(#[source] object_store::Error),
#[error("Failed to load table index snapshot from object store")]
LoadSnapshot(#[source] object_store::Error),
#[error("Failed to deserialize table index snapshot")]
DeserializeSnapshot(#[source] serde_json::Error),
#[error("Failed to persist table index to object store")]
PersistIndex(#[source] object_store::Error),
#[error("Failed to delete table index snapshot from object store")]
DeleteSnapshot(#[source] object_store::Error),
#[error("Cannot merge table indices with mismatched identifiers: {expected} != {actual}")]
MergeMismatch {
expected: TableIndexId,
actual: TableIndexId,
},
#[error("Failed to parse table index path from object store path")]
TableIndexPath(#[source] crate::paths::PathError),
#[error("Failed to parse table index snapshot path from object store path")]
TableIndexSnapshotPath(#[source] crate::paths::PathError),
#[error("Failed to update table index: join task failed")]
UpdateTaskFailed(#[source] tokio::task::JoinError),
#[error("Object meta is missing filename")]
MissingFilename,
#[error("Failed to parse snapshot sequence number from filename")]View on GitHub (pinned to 06200ef96b)