influxdata/influxdb · error · TableIndexError
JSON serialization/deserialization failed
Error message
JSON serialization/deserialization failed
What it means
TableIndexError::Json wraps a serde_json::Error raised when serializing a TableIndexSnapshot to JSON before persisting it, or deserializing a PersistedSnapshot from JSON bytes read out of the object store. It means the snapshot payload could not be converted to/from JSON, typically because the stored bytes are corrupt, truncated, or written by an incompatible schema version.
Solutions
- Locate the offending snapshot file named in the operation log and check whether the JSON is complete and parseable (e.g. with jq).
- If the file is corrupt or from an incompatible older version, restore it from backup or remove/quarantine it so conversion can skip it, then restart.
- Ensure all InfluxDB 3 nodes in the deployment run a compatible version before/after upgrading; complete rolling upgrades rather than mixing versions.
- Rule out interrupted writes: verify upload/complete semantics and disk health on the object store.
Example fix
// before: manually copied a partially-uploaded snapshot file into the snapshot dir // after: only fully-uploaded files are kept; verify first jq . snapshot-0000001234.json >/dev/null || mv snapshot-0000001234.json /quarantine/
Defensive patterns
Strategy: validation
Validate before calling
// validate a snapshot file parses before conversion consumes it
fn validate_snapshot_json(bytes: &[u8]) -> Result<(), serde_json::Error> {
serde_json::from_slice::<serde_json::Value>(bytes).map(|_| ())
} Type guard
fn parse_snapshot(bytes: &[u8]) -> Option<PersistedSnapshotVersion> {
serde_json::from_slice(bytes).ok()
} Try / catch
match serde_json::from_slice::<PersistedSnapshotVersion>(&bytes) {
Ok(s) => process(s),
Err(e) => warn!("skipping corrupt snapshot: {e}; quarantine file"),
} Prevention
- Never hand-edit snapshot files in the object store
- Ensure uploads are atomic/complete before files become visible to conversion
- Keep all InfluxDB 3 nodes on the same version during rolling upgrades
- Back up the snapshot prefix before upgrades
When it happens
Trigger: serde_json::to_vec_pretty(self) fails inside TableIndexSnapshot::persist; serde_json::from_slice::<PersistedSnapshotVersion> fails inside TableIndexSnapshot::load_split_persist when loading a PersistedSnapshot during snapshot-format conversion.
Common situations: A PersistedSnapshot file truncated by a crash or interrupted upload, files written by an older InfluxDB 3 version whose schema no longer deserializes, or manual edits/corruption of files in the snapshot directory.
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
- JSON serialization/deserialization failed
- serde_json error
- error decoding query body
- Failed to deserialize table index
- failed to serialize the request body
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/d99356e90d67f8b5.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_write/src/table_index.rs:79
#[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")]
InvalidSnapshotSequenceNumber,
#[error("Table snapshot persistence task failed")]
TableSnapshotPersistenceTaskFailed(#[source] tokio::task::JoinError),
#[error("Unexpected error")]
Unexpected(#[source] anyhow::Error),
#[error("Object store operation failed")]
ObjectStore(#[source] object_store::Error),
#[error("JSON serialization/deserialization failed")]
Json(#[source] serde_json::Error),
}
pub type Result<T> = std::result::Result<T, TableIndexError>;
/// An partial, incremental index into a given database/table. Should not be used to make decisions
/// regarding gen1 file retention -- instead, all snapshots should be aggregated into a full
/// CoreTableIndex.
///
/// TableIndexSnapshots are expected to be created during the normal snapshotting process alongside
/// the full process-wide database + table index.
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
pub struct TableIndexSnapshot {
#[serde(flatten)]
pub id: TableIndexId,
pub snapshot_sequence_number: SnapshotSequenceNumber,
pub files: HashSet<ParquetFile>,View on GitHub (pinned to 06200ef96b)