{"record":{"id":"63c7e76c65007a68","repo":"influxdata/influxdb","slug":"failed-to-delete-table-index-table-id-from-object-store","errorCode":null,"errorMessage":"Failed to delete table index {table_id} from object store","messagePattern":"Failed to delete table index (.+?) from object store","errorType":"exception","errorClass":"TableIndexCacheError","httpStatus":null,"severity":"error","filePath":"influxdb3_write/src/table_index_cache.rs","lineNumber":112,"sourceCode":"    SplitPersistedSnapshotError(#[source] crate::table_index::TableIndexError),\n\n    #[error(\"Failed to load table index from object store\")]\n    LoadTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),\n\n    #[error(\"Failed to update table index from object store\")]\n    UpdateTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),\n\n    #[error(\"Failed to create table index from object store\")]\n    CreateTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),\n\n    #[error(\"Failed to delete parquet file {path} from object store\")]\n    DeleteParquetFile {\n        path: String,\n        #[source]\n        source: object_store::Error,\n    },\n\n    #[error(\"Failed to delete table index {table_id} from object store\")]\n    DeleteTableIndex {\n        table_id: TableIndexId,\n        #[source]\n        source: object_store::Error,\n    },\n}\n\npub type Result<T> = std::result::Result<T, TableIndexCacheError>;\n\n/// Configuration for the TableIndexCache\n#[derive(Debug, Clone, Copy)]\npub struct TableIndexCacheConfig {\n    /// Maximum number of entries to cache (None = unlimited)\n    pub max_entries: Option<usize>,\n    /// Limit the concurrency of cache <-> object store operations.\n    pub concurrency_limit: usize,\n}\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/table_index_cache.rs#L94-L130","documentation":"TableIndexCacheError::DeleteTableIndex is thrown when deleting the table index object itself from the object store fails. It carries the table_id and wraps an object_store::Error. This occurs during table purge/drop when the final index blob cannot be removed, leaving the table index potentially orphaned in storage.","triggerScenarios":"purge_table / DROP TABLE flows in table_index_cache.rs calling object_store delete on the table index blob, where the store returns an error (permission, network, or store-side failure).","commonSituations":"Service account missing delete rights on the index prefix; object-lock/retention policies protecting index blobs; object store outage or throttling during table drops; repeated drops racing with snapshot persistence.","solutions":["Check the wrapped object_store::Error and the table_id to find the exact blob and failure cause.","Verify IAM delete permissions on the table index prefix in the bucket.","Retry the delete; if the blob is versioned/locked, disable or override the retention policy.","Manually clean up the orphaned index object after fixing the underlying cause."],"exampleFix":"// before\ncache.delete_table_index(table_id).await?;\n// after\nif let Err(e) = cache.delete_table_index(table_id).await {\n  log::error!(\"orphaned index possible for {table_id:?}: {e}\");\n  schedule_orphan_cleanup(table_id);\n}","handlingStrategy":"try-catch","validationCode":"// Rust: confirm the index object exists and is deletable before dropping\nlet exists = object_store.head(&index_path).await.is_ok();\nlet can_delete = iam_allows_delete(&index_path);\nassert!(exists && can_delete, \"cannot delete index blob {index_path}\");","typeGuard":"fn is_delete_index_err(e: &TableIndexCacheError) -> Option<(TableIndexId, &object_store::Error)> {\n  if let TableIndexCacheError::DeleteTableIndex { table_id, source } = e {\n    Some((*table_id, source))\n  } else { None }\n}","tryCatchPattern":"match cache.delete_table_index(table_id).await {\n  Err(TableIndexCacheError::DeleteTableIndex { table_id, source }) => {\n    log::error!(\"index delete failed for {table_id:?}: {source}; scheduling orphan cleanup\");\n    orphan_queue.push(table_id);\n  }\n  Err(e) => return Err(e),\n  Ok(()) => {}\n}","preventionTips":["Include index blobs in the same IAM delete policy scope as parquet files.","Run table drops outside of store maintenance windows/outages.","Reconcile orphaned index objects with a periodic cleanup job.","Log table_id on failure to make manual cleanup straightforward."],"tags":["object-store","delete","table-index","influxdb3"],"backgroundTag":"object-store-operation-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"}