influxdata/influxdb · error · TableIndexCacheError
Failed to delete table index
Error message
Failed to delete table index {table_id} from object store What it means
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.
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.
Example fix
// before
cache.delete_table_index(table_id).await?;
// after
if let Err(e) = cache.delete_table_index(table_id).await {
log::error!("orphaned index possible for {table_id:?}: {e}");
schedule_orphan_cleanup(table_id);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: confirm the index object exists and is deletable before dropping
let exists = object_store.head(&index_path).await.is_ok();
let can_delete = iam_allows_delete(&index_path);
assert!(exists && can_delete, "cannot delete index blob {index_path}"); Type guard
fn is_delete_index_err(e: &TableIndexCacheError) -> Option<(TableIndexId, &object_store::Error)> {
if let TableIndexCacheError::DeleteTableIndex { table_id, source } = e {
Some((*table_id, source))
} else { None }
} Try / catch
match cache.delete_table_index(table_id).await {
Err(TableIndexCacheError::DeleteTableIndex { table_id, source }) => {
log::error!("index delete failed for {table_id:?}: {source}; scheduling orphan cleanup");
orphan_queue.push(table_id);
}
Err(e) => return Err(e),
Ok(()) => {}
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Failed to create table index from object store
- Failed to delete parquet file
- Failed to load table index from object store
- Failed to update table index from object store
- Failed to delete table index snapshot from object store
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/63c7e76c65007a68.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_write/src/table_index_cache.rs:112
SplitPersistedSnapshotError(#[source] crate::table_index::TableIndexError),
#[error("Failed to load table index from object store")]
LoadTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),
#[error("Failed to update table index from object store")]
UpdateTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),
#[error("Failed to create table index from object store")]
CreateTableIndexFromObjectStoreError(#[source] crate::table_index::TableIndexError),
#[error("Failed to delete parquet file {path} from object store")]
DeleteParquetFile {
path: String,
#[source]
source: object_store::Error,
},
#[error("Failed to delete table index {table_id} from object store")]
DeleteTableIndex {
table_id: TableIndexId,
#[source]
source: object_store::Error,
},
}
pub type Result<T> = std::result::Result<T, TableIndexCacheError>;
/// Configuration for the TableIndexCache
#[derive(Debug, Clone, Copy)]
pub struct TableIndexCacheConfig {
/// Maximum number of entries to cache (None = unlimited)
pub max_entries: Option<usize>,
/// Limit the concurrency of cache <-> object store operations.
pub concurrency_limit: usize,
}
View on GitHub (pinned to 06200ef96b)