apache/iceberg · error · AlreadyExistsException

File already exists: %s

Error message

File already exists: %s

What it means

Files local FileIO's create() opens a PositionOutputStream for writing and refuses to overwrite: if the target java.io.File already exists it throws AlreadyExistsException to prevent silently clobbering data files or metadata.

Source

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

  public static OutputFile localOutput(String file) {
    if (file.startsWith("file:")) {
      return localOutput(new File(file.replaceFirst("file:", "")));
    }
    return localOutput(Paths.get(file).toAbsolutePath().toFile());
  }

  private static class LocalOutputFile implements OutputFile {
    private final File file;

    private LocalOutputFile(File file) {
      this.file = file;
    }

    @Override
    public PositionOutputStream create() {
      if (file.exists()) {
        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);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use createOrOverwrite() instead of create() if overwriting is intentional
  2. Generate a unique file name (UUID) per attempt so the path never pre-exists
  3. Delete the stale file (or clean the target directory) before retrying create()

Example fix

// before
OutputFile out = fileIO.newOutputFile(path);
PositionOutputStream stream = out.create();
// after
OutputFile out = fileIO.newOutputFile(path);
PositionOutputStream stream = out.createOrOverwrite();
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(URI.create(location).getPath());
Preconditions.checkArgument(!f.exists(), "File already exists: %s", f);

Try / catch

try {
  stream = outputFile.create();
} catch (AlreadyExistsException e) {
  stream = outputFile.createOrOverwrite(); // or generate a new path
}

Prevention

When it happens

Trigger: Calling fileIO.newOutputFile(location).create() when the file at that location already exists on the local filesystem — e.g. re-running a job that reuses a fixed file path, or a failed earlier attempt left a partial file behind.

Common situations: Idempotency violations: fixed filenames in local warehouse directories without uniqueness (UUID/timestamp); retrying a commit after a partial failure; createOrOverwrite used by mistake vs create semantics.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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