influxdata/influxdb · error · TableIndexCacheError

Failed to delete parquet file

Error message

Failed to delete parquet file {path} from object store

What it means

TableIndexCacheError::DeleteParquetFile is thrown when deleting a parquet file from the object store fails during table index maintenance. Unlike the load/update variants, its #[source] is a raw object_store::Error and it carries the file path, so it directly reports which blob deletion failed and why.

Solutions

  1. Use the path field to identify the exact object, then check the wrapped object_store::Error for permission vs not-found vs network cause.
  2. Grant delete permissions on the bucket/prefix to the node's service account.
  3. Retry the purge — object-store deletes are idempotent in most stores.
  4. Check bucket versioning/immutability (object lock, WORM) settings that can block deletes.

Example fix

// before: aborting purge on first delete failure
store.delete(&path).await?;
// after: tolerate/collect delete failures and continue
if let Err(e) = store.delete(&path).await {
  log::warn!("failed to delete parquet {}: {e}", path);
  failed_deletes.push(path);
}
Defensive patterns

Strategy: retry

Validate before calling

// Rust: check delete permission by a dry-run head + IAM policy check
if object_store.head(&parquet_path).await.is_ok() {
  assert_iam_permission("s3:DeleteObject");
}

Type guard

fn is_delete_parquet_err(e: &TableIndexCacheError) -> Option<(&str, &object_store::Error)> {
  if let TableIndexCacheError::DeleteParquetFile { path, source } = e {
    Some((path.as_str(), source))
  } else { None }
}

Try / catch

match object_store.delete(&path).await {
  Err(e) if e.to_string().contains("AccessDenied") => return Err(perm_error(path, e)),
  Err(e) => { warn!("transient delete failure for {path}: {e}"); retry_delete(path) }
  Ok(_) => {}
}

Prevention

When it happens

Trigger: Purging/dropping table data (purge_table, purge_db, snapshot compaction cleanup) where object_store.delete(path) on a parquet file returns an error — permission denial, network failure, or store-side rejection.

Common situations: IAM credentials lacking s3:DeleteObject / storage.objects.delete permission; lifecycle/retention policies locking or versioning objects; transient object store outages during a purge; wrong bucket configuration so the path doesn't exist in the expected store.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/9147e690e16f20f0. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_write/src/table_index_cache.rs:105

    #[error("Failed to put initial table index conversion marker to object store")]
    PutConversionMarkerError(#[source] object_store::Error),

    #[error("Failed to parse snapshot info file path")]
    ParseSnapshotPathError(#[source] anyhow::Error),

    #[error("Failed to split persisted snapshot into table snapshots")]
    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)]

View on GitHub (pinned to 06200ef96b)