influxdata/influxdb · error · TableIndexCacheError
Failed to split persisted snapshot into table snapshots
Error message
Failed to split persisted snapshot into table snapshots
What it means
TableIndexCacheError::SplitPersistedSnapshotError, thrown when splitting a persisted wal/snapshot into per-table snapshots fails inside the TableIndex layer (wrapping crate::table_index::TableIndexError). The cache converts one catalog snapshot into multiple TableIndexSnapshot objects; a structural problem in the snapshot data aborts the load.
Solutions
- Inspect the inner TableIndexError (via #[source]) to find the specific snapshot field or entry that failed validation
- Restore from a consistent backup or an earlier valid snapshot; ensure restores copy the full snapshot set atomically
- Pin the reader to the same InfluxDB 3 version that wrote the snapshot, or upgrade to a version that reads the newer format
- Delete/rebuild the affected table index from the WAL/parquet data using the recovery tooling, since snapshots are derived state
Example fix
// before: hard fail the whole cache init
let per_table = split_persisted_snapshot(&snap)?;
// after: isolate the failure and fall back to reloading from source parquet
match split_persisted_snapshot(&snap) {
Ok(per_table) => hydrate(per_table),
Err(e) => { error!(error=?e, "snapshot split failed; rebuilding index"); rebuild_index_from_parquet(db_id, table_id).await?; }
} Defensive patterns
Strategy: fallback
Validate before calling
// validate snapshot payload before split
fn snapshot_self_check(snap: &PersistedSnapshot) -> Result<(), String> {
if snap.parquet_files.is_empty() { return Err("empty snapshot".into()); }
if snap.min_sequence_number > snap.max_sequence_number {
return Err("sequence range inverted".into());
}
Ok(())
} Try / catch
match result {
Err(TableIndexCacheError::SplitPersistedSnapshotError(e)) => {
error!(source=?e, "snapshot split failed; falling back to full index rebuild");
rebuild_from_parquet().await?;
}
other => other?,
} Prevention
- Take and restore backups atomically — never partially copy snapshot sets
- Upgrade reader and writer to the same InfluxDB 3 version together
- Verify checksums of snapshot files after restore
- Keep WAL/parquet sources intact so indexes can always be rebuilt from scratch
When it happens
Trigger: Loading a TableIndex from the object store: the persisted snapshot (parquet file list, table mappings, sequence numbers) is split per table; TableIndex methods like split_persisted_snapshot return TableIndexError when entries reference missing tables, sequence gaps, or malformed snapshot payloads.
Common situations: Snapshot JSON corrupted or truncated by an interrupted write/crash; data written by a newer InfluxDB 3 version then read by an older one (schema drift); object store objects manually copied out of order during restore.
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
- Failed to parse snapshot sequence number from filename
- ' ' is a reserved column
- auto field family exists
- cache error
- can only accept once
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/f0e65ea80996fd53.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_write/src/table_index_cache.rs:93
#[error("Failed to update table index: join task failed")]
UpdateTaskFailed(#[source] tokio::task::JoinError),
#[error("Failed to list object store metadata")]
ListMetasError(#[source] object_store::Error),
#[error("Failed to load table index conversion marker bytes from object store")]
LoadConversionMarkerBytesError(#[source] object_store::Error),
#[error("Failed to serialize initial table index conversion marker")]
SerializeConversionMarkerError(#[source] serde_json::Error),
#[error("Failed to put initial table index conversion marker to object store")]
PutConversionMarkerError(#[source] object_store::Error),
#[error("Failed to parse snapshot info file path")]
ParseSnapshotPathError(#[source] anyhow::Error),
#[error("Failed to split persisted snapshot into table snapshots")]
SplitPersistedSnapshotError(#[source] crate::table_index::TableIndexError),
#[error("Failed to load table index from object store")]
LoadTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),
#[error("Failed to update table index from object store")]
UpdateTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),
#[error("Failed to create table index from object store")]
CreateTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),
#[error("Failed to delete parquet file {path} from object store")]
DeleteParquetFile {
path: String,
#[source]
source: object_store::Error,
},
View on GitHub (pinned to 06200ef96b)