{"record":{"id":"eb43599826c3c59c","repo":"apache/iceberg","slug":"deleted-only-of-files-using-bulk-deletes-eb4359","errorCode":null,"errorMessage":"Deleted only {} of {} files using bulk deletes","messagePattern":"Deleted only (.+?) of (.+?) files using bulk deletes","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/DeleteOrphanFilesSparkAction.java","lineNumber":325,"sourceCode":"  }\n\n  private void collectPathsForOutput(\n      List<String> paths, List<String> orphanFileList, int maxSampleSize) {\n    if (streamResults()) {\n      int lengthToAdd = Math.min(maxSampleSize - orphanFileList.size(), paths.size());\n      orphanFileList.addAll(paths.subList(0, lengthToAdd));\n    } else {\n      orphanFileList.addAll(paths);\n    }\n  }\n\n  private void deleteBulk(SupportsBulkOperations io, List<String> paths) {\n    try {\n      io.deleteFiles(paths);\n      LOG.info(\"Deleted {} files using bulk deletes\", paths.size());\n    } catch (BulkDeletionFailureException e) {\n      int deletedFilesCount = paths.size() - e.numberFailedObjects();\n      LOG.warn(\n          \"Deleted only {} of {} files using bulk deletes\", deletedFilesCount, paths.size(), e);\n    }\n  }\n\n  private void deleteNonBulk(List<String> paths) {\n    Tasks.Builder<String> deleteTasks =\n        Tasks.foreach(paths)\n            .noRetry()\n            .executeWith(deleteExecutorService)\n            .suppressFailureWhenFinished()\n            .onFailure((file, exc) -> LOG.warn(\"Failed to delete file: {}\", file, exc));\n\n    if (deleteFunc == null) {\n      LOG.info(\n          \"Table IO {} does not support bulk operations. Using non-bulk deletes.\",\n          table.io().getClass().getName());\n      deleteTasks.run(table.io()::deleteFile);\n    } else {","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/DeleteOrphanFilesSparkAction.java#L307-L343","documentation":"DeleteOrphanFilesSparkAction.deleteBulk uses a FileIO supporting bulk operations (io.deleteFiles). If the bulk delete partially fails, the FileIO throws BulkDeletionFailureException carrying the number of failed objects; the action logs how many of the requested files were actually deleted. Some files remain on storage.","triggerScenarios":"io.deleteFiles(paths) on a SupportsBulkOperations FileIO (e.g. S3FileIO) deletes some objects but fails on others (permissions, throttling, objects already gone), raising BulkDeletionFailureException.","commonSituations":"Large orphan-file cleanups on S3 hitting rate limits; IAM policies lacking s3:DeleteObject on some prefixes; concurrent cleanups deleting the same files.","solutions":["Check the chained BulkDeletionFailureException for which paths failed and fix permissions/bucket policy","Re-run DeleteOrphanFiles to retry the failed deletions","Enable retry/throttling mitigation on the FileIO (e.g. S3 retry settings) or reduce batch size"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  Actions.forTable(table).deleteOrphanFiles().execute();\n} catch (BulkDeletionFailureException e) {\n  // e.numberFailedObjects() files remain; fix cause and re-run\n}","preventionTips":["Verify IAM/storage policies allow DeleteObject on all prefixes","Avoid concurrent orphan-file cleanups","Use S3FileIO with retries for bulk deletes"],"tags":["spark","file-deletion","bulk-delete","object-store"],"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"}