{"record":{"id":"d99356e90d67f8b5","repo":"influxdata/influxdb","slug":"json-serialization-deserialization-failed","errorCode":null,"errorMessage":"JSON serialization/deserialization failed","messagePattern":"JSON serialization/deserialization failed","errorType":"exception","errorClass":"TableIndexError","httpStatus":null,"severity":"error","filePath":"influxdb3_write/src/table_index.rs","lineNumber":79,"sourceCode":"    #[error(\"Failed to update table index: join task failed\")]\n    UpdateTaskFailed(#[source] tokio::task::JoinError),\n\n    #[error(\"Object meta is missing filename\")]\n    MissingFilename,\n\n    #[error(\"Failed to parse snapshot sequence number from filename\")]\n    InvalidSnapshotSequenceNumber,\n\n    #[error(\"Table snapshot persistence task failed\")]\n    TableSnapshotPersistenceTaskFailed(#[source] tokio::task::JoinError),\n\n    #[error(\"Unexpected error\")]\n    Unexpected(#[source] anyhow::Error),\n\n    #[error(\"Object store operation failed\")]\n    ObjectStore(#[source] object_store::Error),\n\n    #[error(\"JSON serialization/deserialization failed\")]\n    Json(#[source] serde_json::Error),\n}\n\npub type Result<T> = std::result::Result<T, TableIndexError>;\n\n/// An partial, incremental index into a given database/table. Should not be used to make decisions\n/// regarding gen1 file retention -- instead, all snapshots should be aggregated into a full\n/// CoreTableIndex.\n///\n/// TableIndexSnapshots are expected to be created during the normal snapshotting process alongside\n/// the full process-wide database + table index.\n#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]\npub struct TableIndexSnapshot {\n    #[serde(flatten)]\n    pub id: TableIndexId,\n    pub snapshot_sequence_number: SnapshotSequenceNumber,\n\n    pub files: HashSet<ParquetFile>,","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/table_index.rs#L61-L97","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: manually copied a partially-uploaded snapshot file into the snapshot dir\n// after: only fully-uploaded files are kept; verify first\njq . snapshot-0000001234.json >/dev/null || mv snapshot-0000001234.json /quarantine/","handlingStrategy":"validation","validationCode":"// validate a snapshot file parses before conversion consumes it\nfn validate_snapshot_json(bytes: &[u8]) -> Result<(), serde_json::Error> {\n    serde_json::from_slice::<serde_json::Value>(bytes).map(|_| ())\n}","typeGuard":"fn parse_snapshot(bytes: &[u8]) -> Option<PersistedSnapshotVersion> {\n    serde_json::from_slice(bytes).ok()\n}","tryCatchPattern":"match serde_json::from_slice::<PersistedSnapshotVersion>(&bytes) {\n    Ok(s) => process(s),\n    Err(e) => warn!(\"skipping corrupt snapshot: {e}; quarantine file\"),\n}","preventionTips":["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"],"tags":["json","serde","rust","serialization"],"backgroundTag":"json-parse-error","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}