influxdata/influxdb · error · TableIndexError

Failed to deserialize table index snapshot

Error message

Failed to deserialize table index snapshot

What it means

TableIndexError::DeserializeSnapshot wraps a serde_json::Error raised when the bytes of a fetched table index snapshot object cannot be parsed into the snapshot struct (PersistedSnapshot/PersistedSnapshotVersion). The object exists but its JSON content is invalid or has an unexpected schema. The serde_json::Error is available as #[source].

Solutions

  1. Download the snapshot object and validate it with jq / serde_json to see the exact parse error
  2. Compare the InfluxDB3 version that wrote the snapshot against the one reading it; upgrade to a compatible version
  3. Delete the corrupt snapshot and rebuild the table index from remaining valid snapshots (or re-persist)
  4. Restore the object from a backup if it was corrupted by an interrupted write

Example fix

// before: reading a snapshot written by a newer schema version
influxdb3 3.0.0 reading snapshots from 3.1.0 -> DeserializeSnapshot
// after: run a version that understands PersistedSnapshotVersion
influxdb3 3.1.0 serve --object-store ...
Defensive patterns

Strategy: fallback

Validate before calling

// validate snapshot JSON before relying on it
serde_json::from_slice::<PersistedSnapshotVersion>(&bytes)
    .map_err(|e| log::error("snapshot JSON invalid: {e}"));

Type guard

fn is_deserialize_snapshot(e: &TableIndexError) -> bool {
    matches!(e, TableIndexError::DeserializeSnapshot(_))
}

Try / catch

match load_snapshot_bytes(key).await {
    Ok(bytes) => match serde_json::from_slice(&bytes) {
        Ok(snap) => snap,
        Err(_) => skip_and_rebuild_from_remaining_snapshots().await?,
    },
    other => other?,
}

Prevention

When it happens

Trigger: serde_json::from_slice on the bytes returned from loading a table index snapshot object (table_index.rs ~205 area / snapshot load path in table_index.rs), mapping parse failures to DeserializeSnapshot.

Common situations: Snapshot object truncated by an interrupted upload or partial multipart completion; snapshot written by a newer/older InfluxDB3 version with a changed PersistedSnapshot schema; manual edits or corruption in the bucket.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/4aab03933c835305. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_write/src/table_index.rs:40

    #[error("Failed to load table index from object store")]
    LoadIndex(#[source] object_store::Error),

    #[error("Failed to deserialize table index")]
    SerializeIndex(#[source] serde_json::Error),

    #[error("Failed to deserialize table index")]
    DeserializeIndex(#[source] serde_json::Error),

    #[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")]

View on GitHub (pinned to 06200ef96b)