apache/iceberg · warning
Delete failed for {}: {}
Error message
Delete failed for {}: {} What it means
BaseSparkAction.deleteFiles removes manifest/data files in parallel via Tasks.foreach with an executor. Individual delete failures do not abort the whole run: this warning logs each failed file (type and path) with its exception, thanks to suppressFailureWhenFinished and the onFailure handler.
Source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/actions/BaseSparkAction.java:255
* @param deleteFunc a delete func
* @param files an iterator of Spark rows of the structure (path: String, type: String)
* @return stats on which files were deleted
*/
protected DeleteSummary deleteFiles(
ExecutorService executorService, Consumer<String> deleteFunc, Iterator<FileInfo> files) {
DeleteSummary summary = new DeleteSummary();
Tasks.foreach(files)
.retry(DELETE_NUM_RETRIES)
.stopRetryOn(NotFoundException.class)
.suppressFailureWhenFinished()
.executeWith(executorService)
.onFailure(
(fileInfo, exc) -> {
String path = fileInfo.getPath();
String type = fileInfo.getType();
LOG.warn("Delete failed for {}: {}", type, path, exc);
})
.run(
fileInfo -> {
String path = fileInfo.getPath();
String type = fileInfo.getType();
deleteFunc.accept(path);
summary.deletedFile(path, type);
});
return summary;
}
protected DeleteSummary deleteFiles(SupportsBulkOperations io, Iterator<FileInfo> files) {
DeleteSummary summary = new DeleteSummary();
Iterator<List<FileInfo>> fileGroups = Iterators.partition(files, DELETE_GROUP_SIZE);
Tasks.foreach(fileGroups)
.suppressFailureWhenFinished()View on GitHub (pinned to 86d9c8fc54)
Solutions
- Review the per-file warn logs to identify which paths failed and why (permissions vs transient).
- Grant the executing credentials delete permission on the storage location (e.g. s3:DeleteObject).
- Re-run the action after fixing transient issues — deletes are idempotent for already-gone files.
- Enable retries or reduce parallelism if the storage layer is throttling (Tasks retry config / executor size).
- Investigate anything not cleaned before removing the action's listing snapshot dependency.
Defensive patterns
Strategy: retry
Validate before calling
// Check delete permission before running the action
FileIO io = table.io();
try {
io.deleteFile(samplePath); // or a canary object in the same location
} catch (Exception e) {
throw new IllegalStateException("Credentials cannot delete files in " + location, e);
} Try / catch
try {
action.execute(result -> LOG.info("deleted {} files", result.deletedDataFilesCount()));
} catch (Exception e) {
LOG.warn("Delete run had failures; inspect per-file warns and retry", e);
} Prevention
- Grant delete permissions (e.g. s3:DeleteObject) to the job's role
- Re-run RemoveOrphanFiles after fixing failures — deletes are idempotent
- Reduce executor parallelism if storage throttles deletes
- Check for concurrent GC jobs deleting the same files
When it happens
Trigger: Actions like RemoveOrphanFiles/DeleteReachableFiles deleting files where some individual deleteFunc.accept(path) calls throw (permission denied, object-store 403, concurrent deletion, network errors) while the executor service processes the file set.
Common situations: Deleting orphan files on S3 with a role lacking s3:DeleteObject; files already removed by a concurrent GC run; throttling/rate limits during mass deletion; HDFS permission mismatches.
Related errors
- Delete failed for {}: {}
- Failed to delete file: {}
- Deleted only {} of {} files using bulk deletes
- Failed to delete file: {}
- Delete failed for {}: {}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/0d305f320a6d42d8.
Report an issue: GitHub.