{"record":{"id":"6d51685235e94e98","repo":"apache/iceberg","slug":"delete-failed-for-6d5168","errorCode":null,"errorMessage":"Delete failed for {}: {}","messagePattern":"Delete failed for (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/BaseSparkAction.java","lineNumber":255,"sourceCode":"   * @param deleteFunc a delete func\n   * @param files an iterator of Spark rows of the structure (path: String, type: String)\n   * @return stats on which files were deleted\n   */\n  protected DeleteSummary deleteFiles(\n      ExecutorService executorService, Consumer<String> deleteFunc, Iterator<FileInfo> files) {\n\n    DeleteSummary summary = new DeleteSummary();\n\n    Tasks.foreach(files)\n        .retry(DELETE_NUM_RETRIES)\n        .stopRetryOn(NotFoundException.class)\n        .suppressFailureWhenFinished()\n        .executeWith(executorService)\n        .onFailure(\n            (fileInfo, exc) -> {\n              String path = fileInfo.getPath();\n              String type = fileInfo.getType();\n              LOG.warn(\"Delete failed for {}: {}\", type, path, exc);\n            })\n        .run(\n            fileInfo -> {\n              String path = fileInfo.getPath();\n              String type = fileInfo.getType();\n              deleteFunc.accept(path);\n              summary.deletedFile(path, type);\n            });\n\n    return summary;\n  }\n\n  protected DeleteSummary deleteFiles(SupportsBulkOperations io, Iterator<FileInfo> files) {\n    DeleteSummary summary = new DeleteSummary();\n    Iterator<List<FileInfo>> fileGroups = Iterators.partition(files, DELETE_GROUP_SIZE);\n\n    Tasks.foreach(fileGroups)\n        .suppressFailureWhenFinished()","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/BaseSparkAction.java#L237-L273","documentation":"BaseSparkAction.deleteFiles runs file deletions in parallel via Tasks with failure suppression; when an individual delete fails, the onFailure handler logs 'Delete failed for <type>: <path>' with the exception and deletion continues for other files. The overall action may finish even though some files were not deleted, so orphan/obsolete files can remain.","triggerScenarios":"deleteFunc (e.g. io.deleteFile) throws for a specific file during rewrite/expire actions — storage permissions issues, S3 throttling, or the file already being deleted by another process.","commonSituations":"Concurrent ExpireSnapshots/DeleteOrphanFiles runs racing each other; bucketing/permissions changes mid-run; transient S3 503s under heavy delete load.","solutions":["Inspect each logged path/exception to determine whether failures are transient and re-run the action","Avoid concurrent delete actions on the same table (they race to delete the same files)","Add retry/backoff or reduce delete concurrency if the storage layer is throttling"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  Actions.forTable(table).rewriteDataFiles().execute();\n} catch (Exception e) {\n  // check logs for 'Delete failed for <type>: <path>' entries and re-run\n}","preventionTips":["Avoid overlapping delete actions on one table","Ensure delete permissions on all relevant prefixes","Tune executor/storage retry settings"],"tags":["spark","file-deletion","concurrency","storage"],"backgroundTag":"http-request-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}