apache/iceberg · warning

Deleted only {} of {} files using bulk deletes

Error message

Deleted only {} of {} files using bulk deletes

What it means

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.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/DeleteOrphanFilesSparkAction.java:325

  }

  private void collectPathsForOutput(
      List<String> paths, List<String> orphanFileList, int maxSampleSize) {
    if (streamResults()) {
      int lengthToAdd = Math.min(maxSampleSize - orphanFileList.size(), paths.size());
      orphanFileList.addAll(paths.subList(0, lengthToAdd));
    } else {
      orphanFileList.addAll(paths);
    }
  }

  private void deleteBulk(SupportsBulkOperations io, List<String> paths) {
    try {
      io.deleteFiles(paths);
      LOG.info("Deleted {} files using bulk deletes", paths.size());
    } catch (BulkDeletionFailureException e) {
      int deletedFilesCount = paths.size() - e.numberFailedObjects();
      LOG.warn(
          "Deleted only {} of {} files using bulk deletes", deletedFilesCount, paths.size(), e);
    }
  }

  private void deleteNonBulk(List<String> paths) {
    Tasks.Builder<String> deleteTasks =
        Tasks.foreach(paths)
            .noRetry()
            .executeWith(deleteExecutorService)
            .suppressFailureWhenFinished()
            .onFailure((file, exc) -> LOG.warn("Failed to delete file: {}", file, exc));

    if (deleteFunc == null) {
      LOG.info(
          "Table IO {} does not support bulk operations. Using non-bulk deletes.",
          table.io().getClass().getName());
      deleteTasks.run(table.io()::deleteFile);
    } else {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the chained BulkDeletionFailureException for which paths failed and fix permissions/bucket policy
  2. Re-run DeleteOrphanFiles to retry the failed deletions
  3. Enable retry/throttling mitigation on the FileIO (e.g. S3 retry settings) or reduce batch size
Defensive patterns

Strategy: retry

Try / catch

try {
  Actions.forTable(table).deleteOrphanFiles().execute();
} catch (BulkDeletionFailureException e) {
  // e.numberFailedObjects() files remain; fix cause and re-run
}

Prevention

When it happens

Trigger: io.deleteFiles(paths) on a SupportsBulkOperations FileIO (e.g. S3FileIO) deletes some objects but fails on others (permissions, throttling, objects already gone), raising BulkDeletionFailureException.

Common situations: Large orphan-file cleanups on S3 hitting rate limits; IAM policies lacking s3:DeleteObject on some prefixes; concurrent cleanups deleting the same files.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/eb43599826c3c59c. Report an issue: GitHub.