apache/iceberg · warning · RuntimeException
Interrupted when waiting for deletions to complete
Error message
Interrupted when waiting for deletions to complete
What it means
RuntimeException thrown by S3FileIO.deleteFiles when the thread waiting on the batch deletion tasks is interrupted. The method re-interrupts the current thread, cancels all outstanding deletion tasks, and wraps the InterruptedException in a RuntimeException. It signals the caller's shutdown/interrupt rather than an S3 problem.
Source
Thrown at aws/src/main/java/org/apache/iceberg/aws/s3/S3FileIO.java:264
Future<List<String>> deletionTask =
executorService()
.submit(() -> deleteBatch(clientForStoragePath("s3://" + bucket), bucket, keys));
deletionTasks.add(deletionTask);
}
int totalFailedDeletions = 0;
for (Future<List<String>> deletionTask : deletionTasks) {
try {
List<String> failedDeletions = deletionTask.get();
failedDeletions.forEach(path -> LOG.warn("Failed to delete object at path {}", path));
totalFailedDeletions += failedDeletions.size();
} catch (ExecutionException e) {
LOG.warn("Caught unexpected exception during batch deletion: ", e.getCause());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
deletionTasks.stream().filter(task -> !task.isDone()).forEach(task -> task.cancel(true));
throw new RuntimeException("Interrupted when waiting for deletions to complete", e);
}
}
if (totalFailedDeletions > 0) {
throw new BulkDeletionFailureException(totalFailedDeletions);
}
}
}
private void tagFileToDelete(PrefixedS3Client client, String path, Set<Tag> deleteTags)
throws S3Exception {
S3URI location = new S3URI(path, client.s3FileIOProperties().bucketToAccessPointMapping());
String bucket = location.bucket();
String objectKey = location.key();
GetObjectTaggingRequest getObjectTaggingRequest =
GetObjectTaggingRequest.builder().bucket(bucket).key(objectKey).build();
GetObjectTaggingResponse getObjectTaggingResponse =
client.s3().getObjectTagging(getObjectTaggingRequest);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Avoid interrupting the thread during deleteFiles; ensure graceful shutdown lets cleanup finish or accepts partial deletion (S3 deletes are per-object, retryable).
- Re-run the deletion — file deletes are idempotent for already-deleted keys; re-invoke deleteFiles after the interruption.
- If interruption is expected (job cancellation), catch RuntimeException at the call site and check Thread.currentThread().isInterrupted() to restore/record the interrupt state.
- Move large bulk deletions to a dedicated lifecycle/expiration job less likely to be interrupted.
Example fix
// before
io.deleteFiles(filesToDelete); // running inside a cancellable Spark task, interrupted on job kill
// after
try {
io.deleteFiles(filesToDelete);
} catch (RuntimeException e) {
if (Thread.currentThread().isInterrupted()) {
LOG.warn("Deletion interrupted, will retry on restart", e);
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Try / catch
try {
io.deleteFiles(paths);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Interrupted when waiting for deletions")) {
Thread.currentThread().interrupt(); // preserve interrupt status
LOG.warn("Bulk deletion interrupted; deletes are idempotent, retry later");
} else {
throw e;
}
} Prevention
- Allow graceful shutdown so deletion cleanup can finish
- Treat file deletions as idempotent and safe to re-run
- Run bulk deletes in dedicated maintenance jobs less prone to interruption
- Avoid Thread.interrupt on threads performing FileIO cleanup
When it happens
Trigger: deleteFiles (also invoked via deletePrefix) waiting on futures of S3 batch deletion tasks when the executing thread is interrupted — e.g. task cancellation in Spark/Flink, executor shutdown, or Thread.interrupt() during cleanup.
Common situations: Cancelling a Spark job whose ExpireSnapshots/deleteFiles cleanup is in flight; shutting down an executor while bulk deletes are running; a query killed by a timeout mechanism that interrupts threads; Flink task manager failover interrupting cleanup threads.
Related errors
- Caught unexpected exception during batch deletion:
- Cannot initialize S3FileIOAwsClientFactory, missing no-arg c
- Cannot initialize S3FileIOAwsClientFactory, %s does not impl
- Cannot commit %s: concurrent update detected
- Cannot commit %s because base metadata location '%s' is not
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/35f709869c6398f6.
Report an issue: GitHub.