apache/iceberg · error · NotFoundException

Failed to create file: %s

Error message

Failed to create file: %s

What it means

After validating existence and parent directory, create() opens the file with new RandomAccessFile(file, "rw"). A FileNotFoundException here means the file could not be opened (e.g. permission denied, path is a directory, or too many open files), wrapped as NotFoundException with the target file in the message.

Source

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

    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);
      }
      return create();
    }

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

    @Override
    public InputFile toInputFile() {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the process can create files in the parent directory (touch a test file as the same user)
  2. Ensure the target path is not an existing directory and the filesystem is writable and not full
  3. Check open-file limits (ulimit -n) if this occurs under heavy concurrency; close leaked streams

Example fix

// before
PositionOutputStream s = fileIO.newOutputFile(dir + "/data").create();
// after
File target = new File(dir + "/data");
Preconditions.checkArgument(!target.isDirectory(), "Path is a directory: %s", target);
PositionOutputStream s = fileIO.newOutputFile(target.getPath()).create();
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(URI.create(location).getPath());
Preconditions.checkState(!f.isDirectory(), "Target is a directory: %s", f);
Preconditions.checkState(f.getParentFile().canWrite(), "Parent not writable: %s", f.getParentFile());

Try / catch

try {
  stream = outputFile.create();
} catch (NotFoundException e) {
  throw new IllegalStateException("File open failed: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Parent directory exists and file doesn't, but opening "rw" fails: process lacks permission to create files in the directory, a directory exists at the target path, the filesystem is full/read-only, or the file was deleted between the exists() check and open.

Common situations: Read-only volumes or sandboxed processes writing outside allowed dirs; SELinux/AppArmor denials; ulimit -n exhaustion in long-running jobs; racing writers deleting the same path.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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