{"record":{"id":"b615e33f9a1001bf","repo":"influxdata/influxdb","slug":"failed-to-list-table-indices-from-object-store-index-cache","errorCode":null,"errorMessage":"Failed to list table indices from object store","messagePattern":"Failed to list table indices from object store","errorType":"exception","errorClass":"TableIndexCacheError","httpStatus":null,"severity":"error","filePath":"influxdb3_write/src/table_index_cache.rs","lineNumber":63,"sourceCode":"    #[error(\"JSON serialization/deserialization failed\")]\n    Json(#[source] serde_json::Error),\n\n    #[error(\"TableIndex operation failed\")]\n    TableIndex(#[source] crate::table_index::TableIndexError),\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(\"Unexpected error\")]\n    Unexpected(#[source] anyhow::Error),\n\n    #[error(\"Table snapshot persistence task failed\")]\n    TableSnapshotPersistenceTaskFailed(#[source] tokio::task::JoinError),\n\n    #[error(\"Failed to list table indices from object store\")]\n    ListIndices(#[source] object_store::Error),\n\n    #[error(\"Failed to parse table index path from object store path\")]\n    TableIndexPath(#[source] crate::paths::PathError),\n\n    #[error(\"Failed to list table index snapshots from object store\")]\n    ListSnapshots(#[source] object_store::Error),\n\n    #[error(\"Failed to parse table index snapshot path from object store path\")]\n    TableIndexSnapshotPath(#[source] crate::paths::PathError),\n\n    #[error(\"Failed to update table index: join task failed\")]\n    UpdateTaskFailed(#[source] tokio::task::JoinError),\n\n    #[error(\"Failed to list object store metadata\")]\n    ListMetasError(#[source] object_store::Error),\n\n    #[error(\"Failed to load table index conversion marker bytes from object store\")]","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/table_index_cache.rs#L45-L81","documentation":"TableIndexCacheError::ListIndices wraps an object_store::Error raised when listing table index objects from the object store fails. The cache lists all table index paths under the node's prefix (e.g. during purge_db or update_all_from_object_store) and this variant signals that listing itself failed, independent of any per-path parsing.","triggerScenarios":"object_store.list(Some(&prefix)) stream errors while collecting table index paths in purge_db (table_index_cache.rs:770) or update_all_from_object_store (table_index_cache.rs:1188); note the list call itself returns Err lazily from the stream.","commonSituations":"S3 ListObjects permission missing (s3:ListBucket), throttling on list APIs during large-prefix scans, network failures mid-pagination, or a mistyped node identifier prefix pointing at a non-listable location.","solutions":["Inspect the wrapped object_store::Error; for permission failures, grant ListBucket/ListBlob permissions on the index prefix.","Verify the node identifier prefix and bucket configuration are correct and the prefix exists (or is expected to be empty).","For throttling on large prefixes, reduce listing concurrency or enable/raise retries with backoff.","Retry the operation (purge_db / initialize) once the object store is reachable again."],"exampleFix":"// before: IAM policy without list permission\n{ \"Effect\": \"Allow\", \"Action\": [\"s3:GetObject\", \"s3:PutObject\"], \"Resource\": \"arn:aws:s3:::my-bucket/*\" }\n// after: add list permission on the bucket\n{ \"Effect\": \"Allow\", \"Action\": [\"s3:GetObject\", \"s3:PutObject\", \"s3:ListBucket\"], \"Resource\": [\"arn:aws:s3:::my-bucket/*\", \"arn:aws:s3:::my-bucket\"] }","handlingStrategy":"retry","validationCode":"// verify list permission before operations that scan the index prefix\nobject_store.list(Some(&indices_prefix)).try_next().await?; // surfaces list errors early\n","typeGuard":"fn is_list_indices_err(e: &TableIndexCacheError) -> Option<&object_store::Error> {\n    match e { TableIndexCacheError::ListIndices(oe) => Some(oe), _ => None }\n}","tryCatchPattern":"match stream.map_err(TableIndexCacheError::ListIndices).try_collect::<Vec<_>>().await {\n    Err(TableIndexCacheError::ListIndices(e)) if retryable(e) => backoff_and_relist().await,\n    other => other?,\n}","preventionTips":["Grant list permissions (s3:ListBucket / storage.buckets.list) on the index prefix","Break very large prefixes into per-database listings to avoid list throttling","Validate the node identifier prefix configuration at startup","Retry list operations with backoff — list APIs are throttled more aggressively than get/put"],"tags":["object-store","listing","rust","permissions"],"backgroundTag":"http-error-response","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"}