{"record":{"id":"6bd8abe25001475c","repo":"apache/iceberg","slug":"delete-failed-for-file","errorCode":null,"errorMessage":"Delete failed for {} file: {}","messagePattern":"Delete failed for (.+?) file: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/FileCleanupStrategy.java","lineNumber":131,"sourceCode":"            \"Bulk deletion failed for {} of {} {} file(s)\",\n            e.numberFailedObjects(),\n            pathsToDelete.size(),\n            fileType,\n            e);\n      } catch (RuntimeException e) {\n        LOG.warn(\"Bulk deletion failed\", e);\n      }\n    } else {\n      Consumer<String> deleteFuncToUse = deleteFunc == null ? defaultDeleteFunc : deleteFunc;\n\n      Tasks.foreach(pathsToDelete)\n          .executeWith(deleteExecutorService)\n          .retry(3)\n          .stopRetryOn(NotFoundException.class)\n          .stopOnFailure()\n          .suppressFailureWhenFinished()\n          .onFailure(\n              (file, thrown) -> LOG.warn(\"Delete failed for {} file: {}\", fileType, file, thrown))\n          .run(deleteFuncToUse::accept);\n    }\n  }\n\n  protected boolean hasAnyStatisticsFiles(TableMetadata tableMetadata) {\n    return !tableMetadata.statisticsFiles().isEmpty()\n        || !tableMetadata.partitionStatisticsFiles().isEmpty();\n  }\n\n  protected Set<String> expiredStatisticsFilesLocations(\n      TableMetadata beforeExpiration, TableMetadata afterExpiration) {\n    Set<String> statsFileLocationsBeforeExpiration = statsFileLocations(beforeExpiration);\n    Set<String> statsFileLocationsAfterExpiration = statsFileLocations(afterExpiration);\n\n    return Sets.difference(statsFileLocationsBeforeExpiration, statsFileLocationsAfterExpiration);\n  }\n\n  private Set<String> statsFileLocations(TableMetadata tableMetadata) {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/FileCleanupStrategy.java#L113-L149","documentation":"In the per-file (non-bulk) delete path, Tasks retries each deletion 3 times (stopping on NotFoundException); if a file still fails after retries, this WARN 'Delete failed for {fileType} file: {file}' is logged per file. The operation continues with the remaining files; the failed file may become an orphan that a later cleanup run must remove.","triggerScenarios":"expireSnapshots/deleteFiles runs with a custom deleteFunc or default delete path, and deleting a single path throws (transient S3/GCS error, permission denied, throttling) on all 3 retries; NotFoundException short-circuits as the file is already gone.","commonSituations":"Object-store eventual consistency where the file was already removed by a concurrent expiration; IAM policies denying DeleteObject on some prefixes; network blips during large snapshot expiration.","solutions":["Inspect the logged exception for the specific file to determine the storage-side cause (403 vs 5xx vs timeout).","Re-run snapshot expiration later — file cleanup is idempotent and already-deleted files stop retrying via NotFoundException.","Verify IAM/storage permissions for the exact prefix of failing files.","Lower concurrency (deleteExecutorService) if deletions are being throttled."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify FileIO can delete in the target prefix before large cleanups\nString probe = prefix + \"/__probe_\" + UUID.randomUUID();\nio.deleteFile(probe);","typeGuard":null,"tryCatchPattern":"try {\n  table.expireSnapshots().execute();\n} catch (RuntimeException e) {\n  LOG.warn(\"Snapshot expiration finished with per-file delete warnings\", e);\n}","preventionTips":["Check per-file WARN causes for 403 vs throttling and fix IAM or rate limits accordingly.","Re-run expiration — it is idempotent; already-deleted files stop via NotFoundException.","Cap deleteExecutorService concurrency if the object store throttles.","Rely on remove-orphan-files as a periodic safety net."],"tags":["io","deletion","retry","object-store"],"backgroundTag":"network-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"}