{"record":{"id":"9147e690e16f20f0","repo":"influxdata/influxdb","slug":"failed-to-delete-parquet-file-path-from-object-store","errorCode":null,"errorMessage":"Failed to delete parquet file {path} from object store","messagePattern":"Failed to delete parquet file (.+?) from object store","errorType":"exception","errorClass":"TableIndexCacheError","httpStatus":null,"severity":"error","filePath":"influxdb3_write/src/table_index_cache.rs","lineNumber":105,"sourceCode":"    #[error(\"Failed to put initial table index conversion marker to object store\")]\n    PutConversionMarkerError(#[source] object_store::Error),\n\n    #[error(\"Failed to parse snapshot info file path\")]\n    ParseSnapshotPathError(#[source] anyhow::Error),\n\n    #[error(\"Failed to split persisted snapshot into table snapshots\")]\n    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)]","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/table_index_cache.rs#L87-L123","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use the path field to identify the exact object, then check the wrapped object_store::Error for permission vs not-found vs network cause.","Grant delete permissions on the bucket/prefix to the node's service account.","Retry the purge — object-store deletes are idempotent in most stores.","Check bucket versioning/immutability (object lock, WORM) settings that can block deletes."],"exampleFix":"// before: aborting purge on first delete failure\nstore.delete(&path).await?;\n// after: tolerate/collect delete failures and continue\nif let Err(e) = store.delete(&path).await {\n  log::warn!(\"failed to delete parquet {}: {e}\", path);\n  failed_deletes.push(path);\n}","handlingStrategy":"retry","validationCode":"// Rust: check delete permission by a dry-run head + IAM policy check\nif object_store.head(&parquet_path).await.is_ok() {\n  assert_iam_permission(\"s3:DeleteObject\");\n}","typeGuard":"fn is_delete_parquet_err(e: &TableIndexCacheError) -> Option<(&str, &object_store::Error)> {\n  if let TableIndexCacheError::DeleteParquetFile { path, source } = e {\n    Some((path.as_str(), source))\n  } else { None }\n}","tryCatchPattern":"match object_store.delete(&path).await {\n  Err(e) if e.to_string().contains(\"AccessDenied\") => return Err(perm_error(path, e)),\n  Err(e) => { warn!(\"transient delete failure for {path}: {e}\"); retry_delete(path) }\n  Ok(_) => {}\n}","preventionTips":["Grant s3:DeleteObject / storage.objects.delete on the data prefix to the writer's service account.","Disable object-lock/versioning retention that blocks deletes on parquet files.","Treat deletes as idempotent and retry transient failures.","Alert on delete-failure counters so orphans are caught early."],"tags":["object-store","delete","parquet","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"}