apache/iceberg · error · RuntimeIOException

Failed to delete: %s

Error message

Failed to delete: %s

What it means

createOrOverwrite() deletes an existing file before delegating to create(). If File.delete() fails when the file exists, it throws RuntimeIOException; on POSIX delete can fail with open handles or missing write permission on the parent directory.

Source

Thrown at api/src/main/java/org/apache/iceberg/Files.java:77

        throw new AlreadyExistsException("File already exists: %s", file);
      }

      if (!file.getParentFile().isDirectory() && !file.getParentFile().mkdirs()) {
        throw new RuntimeIOException(
            "Failed to create the file's directory at %s.", file.getParentFile().getAbsolutePath());
      }

      try {
        return new PositionFileOutputStream(file, new RandomAccessFile(file, "rw"));
      } catch (FileNotFoundException e) {
        throw new NotFoundException(e, "Failed to create file: %s", file);
      }
    }

    @Override
    public PositionOutputStream createOrOverwrite() {
      if (file.exists() && !file.delete()) {
        throw new RuntimeIOException("Failed to delete: %s", file);
      }
      return create();
    }

    @Override
    public String location() {
      return file.toString();
    }

    @Override
    public InputFile toInputFile() {
      return localInput(file);
    }

    @Override
    public String toString() {
      return location();
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Ensure no other process or stream holds the file open (close prior OutputStreams; serialize writers)
  2. Check parent-directory write permission, required to unlink entries on POSIX filesystems
  3. If overwrites are unsafe, switch to unique per-attempt file names instead of overwriting

Example fix

// before
PositionOutputStream s = fileIO.newOutputFile(fixedPath).createOrOverwrite();
// after
File f = new File(fixedPath);
if (f.exists() && !f.delete()) {
  throw new IllegalStateException("File locked or undeletable, pick a new path: " + f);
}
PositionOutputStream s = fileIO.newOutputFile(fixedPath).createOrOverwrite();
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(URI.create(location).getPath());
if (f.exists()) {
  Preconditions.checkState(f.delete(), "Undeletable file: %s", f);
}

Try / catch

try {
  stream = outputFile.createOrOverwrite();
} catch (RuntimeIOException e) {
  throw new IllegalStateException("Delete failed; file may be locked: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling createOrOverwrite() on a path whose existing file cannot be deleted — file is locked/open by another process/thread, parent directory lacks write permission, or filesystem denies unlink (e.g. read-only mount, stale NFS handle).

Common situations: Two concurrent jobs writing the same metadata/data path; Windows file locking by an indexer/AV or an unclosed stream in the same JVM; container with read-only layer; NFS semantics delays.

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/88a8659a29bbcafe. Report an issue: GitHub.