{"record":{"id":"d57dd56b630c52ec","repo":"influxdata/influxdb","slug":"failed-to-load-table-index-from-object-store","errorCode":null,"errorMessage":"Failed to load table index from object store","messagePattern":"Failed to load table index from object store","errorType":"error_code","errorClass":"TableIndexError","httpStatus":null,"severity":"error","filePath":"influxdb3_write/src/table_index.rs","lineNumber":22,"sourceCode":"use hashbrown::{HashMap, HashSet};\nuse object_store::ObjectStore;\nuse object_store_utils::RetryableObjectStore;\nuse observability_deps::tracing::{debug, warn};\nuse serde::{Deserialize, Serialize};\nuse thiserror::Error;\nuse tokio::sync::Semaphore;\n\nuse influxdb3_id::{DbId, ParquetFileId, TableId, TableIndexId};\nuse influxdb3_wal::SnapshotSequenceNumber;\n\nuse crate::{\n    ParquetFile, PersistedSnapshot, PersistedSnapshotVersion,\n    paths::{SnapshotInfoFilePath, TableIndexPath, TableIndexSnapshotPath},\n};\n\n#[derive(Debug, Error)]\npub enum TableIndexError {\n    #[error(\"Failed to load table index from object store\")]\n    LoadIndex(#[source] object_store::Error),\n\n    #[error(\"Failed to deserialize table index\")]\n    SerializeIndex(#[source] serde_json::Error),\n\n    #[error(\"Failed to deserialize table index\")]\n    DeserializeIndex(#[source] serde_json::Error),\n\n    #[error(\"Failed to list table index snapshots from object store\")]\n    ListSnapshots(#[source] object_store::Error),\n\n    #[error(\"Failed to list table indices from object store\")]\n    ListIndices(#[source] object_store::Error),\n\n    #[error(\"Failed to load table index snapshot from object store\")]\n    LoadSnapshot(#[source] object_store::Error),\n\n    #[error(\"Failed to deserialize table index snapshot\")]","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/table_index.rs#L4-L40","documentation":"TableIndexError::LoadIndex is returned when fetching the serialized table index from the object store fails with an object_store::Error. The table index maps each table to its snapshots and is read from a well-known object-store key; any GET failure (missing, network, credentials, throttling) is wrapped here. The object_store::Error is preserved as the #[source].","triggerScenarios":"Calling CoreTableIndex/table_index load paths that issue a get() on the index object and map the Err to LoadIndex (table_index.rs ~316-328); a NotFound error on the index key also lands here.","commonSituations":"First startup against an empty bucket where the index has never been persisted; wrong bucket/endpoint/credentials configured for the object store; network partitions or S3 503s during reads.","solutions":["Check #[source] object_store::Error: if NotFound, treat as a fresh/empty index and create one rather than failing","Verify object-store URL, bucket, credentials, and region in the InfluxDB3 configuration","Test raw access to the index key with the same client credentials (aws s3 cp / az cli)","Retry the load; transient object-store errors are common under rate limiting","If the index was manually deleted, re-persist it via the writer's snapshot flow"],"exampleFix":"// before: fail hard when index object is absent\nlet idx = index.load().await?;\n// after: treat NotFound as an empty index\nlet idx = match index.load().await {\n    Err(e) if matches!(e, TableIndexError::LoadIndex(ref oe) if oe.not_found()) => Default::default(),\n    other => other?,\n};","handlingStrategy":"retry","validationCode":"// check object-store reachability before calling load\nclient.head(&index_path).await?; // surfaces NotFound early so you can treat as empty index","typeGuard":"fn is_load_index_not_found(e: &TableIndexError) -> bool {\n    matches!(e, TableIndexError::LoadIndex(oe) if oe.not_found())\n}","tryCatchPattern":"match load_result {\n    Err(e) if is_load_index_not_found(&e) => TableIndex::default(), // fresh start\n    Err(e) if is_transient(&e) => retry_with_backoff(load, 3),\n    other => other?,\n}","preventionTips":["Verify bucket, endpoint, and credentials at startup with a smoke-test HEAD/GET","Provision IAM with GET on the data prefix","Implement bounded retry with exponential backoff for object-store GETs","Treat index NotFound as a cold start, not a fatal error"],"tags":["object-store","io","table-index","rust"],"backgroundTag":"file-read-failed","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"}