apache/iceberg · warning

Encountered failure when deleting batch

Error message

Encountered failure when deleting batch

What it means

S3FileIO.deleteBatch() wraps the S3 client's batch deleteObjects call. Any exception from the AWS SDK (network failure, throttling, auth error) is caught, logged with this message, and all keys in the batch are added to the failures list so callers can retry them. The original exception is attached to the log entry.

Solutions

  1. Retry the failed paths — they are returned/logged for exactly this purpose
  2. Check the attached exception: 503/SlowDown means reduce batch size or add backoff
  3. Refresh or widen credential lifetime (session token expiry)
  4. Verify S3 endpoint/region configuration, especially with custom endpoints

Example fix

// before: huge batches with no tuning
props.put("s3.delete.batch-size", "5000");
// after: smaller batch reduces throttling
props.put("s3.delete.batch-size", "256");
Defensive patterns

Strategy: retry

Validate before calling

// pre-check credentials and endpoint reachability
s3Client.headBucket(b -> b.bucket(bucket));

Try / catch

try { io.deleteFiles(paths); } catch (RuntimeException e) { /* batch-level SDK errors are logged; failed keys are recoverable */ retryLater(paths); }

Prevention

When it happens

Trigger: deleteFiles() with batches large enough to trigger S3 throttling; expired credentials mid-run; network interruption during DeleteObjects; SDK client misconfiguration.

Common situations: Very high delete throughput causing 503 slow-down responses; STS credentials expiring during long compaction jobs; connectivity issues in on-prem/MinIO S3-compatible storage.

Related errors


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

Appendix: source

Thrown at aws/src/main/java/org/apache/iceberg/aws/s3/S3FileIO.java:320

        keysToDelete.stream()
            .map(key -> ObjectIdentifier.builder().key(key).build())
            .collect(Collectors.toList());
    DeleteObjectsRequest request =
        DeleteObjectsRequest.builder()
            .bucket(bucket)
            .delete(Delete.builder().objects(objectIds).build())
            .build();
    List<String> failures = Lists.newArrayList();
    try {
      DeleteObjectsResponse response = client.s3().deleteObjects(request);
      if (response.hasErrors()) {
        failures.addAll(
            response.errors().stream()
                .map(error -> String.format("s3://%s/%s", request.bucket(), error.key()))
                .collect(Collectors.toList()));
      }
    } catch (Exception e) {
      LOG.warn("Encountered failure when deleting batch", e);
      failures.addAll(
          request.delete().objects().stream()
              .map(obj -> String.format("s3://%s/%s", request.bucket(), obj.key()))
              .collect(Collectors.toList()));
    }
    return failures;
  }

  @Override
  public Iterable<FileInfo> listPrefix(String prefix) {
    PrefixedS3Client client = clientForStoragePath(prefix);

    S3URI uri = new S3URI(prefix, client.s3FileIOProperties().bucketToAccessPointMapping());
    if (uri.useS3DirectoryBucket()
        && client.s3FileIOProperties().isS3DirectoryBucketListPrefixAsDirectory()) {
      uri = uri.toDirectoryPath();
    }

View on GitHub (pinned to 86d9c8fc54)