apache/iceberg · warning

Failed to delete

Error message

Failed to delete: {}

What it means

This is a WARN logged by BaseRewriteDataFilesAction when cleanup of files added by a failed rewrite commit cannot be deleted. After a rewrite commit fails with a CleanableFailure, the action attempts to delete the newly written data files; the onFailure handler logs each per-file deletion error. It does not abort the original exception, which is rethrown after cleanup.

Solutions

  1. Inspect the chained exception in the WARN for the actual delete failure cause (permissions, throttling, 404).
  2. Check the FileIO/credential configuration used for the table has delete permissions on the table's data location.
  3. Re-run the rewrite action; leftover files can also be removed by expireSnapshots/orphan-file cleanup since they were never committed.
  4. If 404-style errors, verify no concurrent cleanup job is racing the rewrite.

Example fix

// before
FileIO io = table.io();
// after
// ensure credentials allow delete, or configure a FileIO with correct permissions
HadoopFileIO io = new HadoopFileIO(hadoopConf); // with fs perms granting delete on data dir
Defensive patterns

Strategy: fallback

Validate before calling

// before rewrite
import org.apache.iceberg.ManifestFiles;
// confirm FileIO can delete in data dir (dry-run a harmless op / check perms)
// e.g. verify credentials:
// fileIO io configured with permissions for s3://bucket/table/data

Try / catch

try {
  action.execute();
} catch (Exception e) {
  // cleanup failures are logged and suppressed; inspect logs for 'Failed to delete'
  throw e;
}

Prevention

When it happens

Trigger: execute() of RewriteDataFilesAction starts, writes new data files, the commit throws a CleanableFailure, and then fileIO.deleteFile(location) fails for one or more of the added files (e.g. object-store eventual consistency, permissions, or the file was already removed).

Common situations: S3/GCS permission or throttling during cleanup; a concurrent process already deleted the files; FileIO configured without delete capability; transient network errors during bulk delete.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/actions/BaseRewriteDataFilesAction.java:318

    return tasksGroupedByPartition.asMap();
  }

  private void replaceDataFiles(
      Iterable<DataFile> deletedDataFiles,
      Iterable<DataFile> addedDataFiles,
      long startingSnapshotId) {
    try {
      doReplace(deletedDataFiles, addedDataFiles, startingSnapshotId);
    } catch (CommitStateUnknownException e) {
      LOG.warn("Commit state unknown, cannot clean up files that may have been committed", e);
      throw e;
    } catch (Exception e) {
      if (e instanceof CleanableFailure) {
        LOG.warn("Failed to commit rewrite, cleaning up rewritten files", e);
        Tasks.foreach(Iterables.transform(addedDataFiles, ContentFile::location))
            .noRetry()
            .suppressFailureWhenFinished()
            .onFailure((location, exc) -> LOG.warn("Failed to delete: {}", location, exc))
            .run(fileIO::deleteFile);
      }

      throw e;
    }
  }

  @VisibleForTesting
  void doReplace(
      Iterable<DataFile> deletedDataFiles,
      Iterable<DataFile> addedDataFiles,
      long startingSnapshotId) {
    RewriteFiles rewriteFiles = table.newRewrite().validateFromSnapshot(startingSnapshotId);

    for (DataFile dataFile : deletedDataFiles) {
      rewriteFiles.deleteFile(dataFile);
    }

View on GitHub (pinned to 86d9c8fc54)