juicedata/juicefs · error · FileAlreadyExistsException

File already exists: " + f

Error message

File already exists: " + f

What it means

Thrown by create() when the native jfs_create returns EEXIST and the requested CreateFlag does not include OVERWRITE, or the target is a directory. The file exists and the caller refused overwrite, so the call fails with FileAlreadyExistsException per Hadoop semantics.

Source

Thrown at sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java:1505

    }
    return size;
  }

  @Override
  public FSDataOutputStream createNonRecursive(Path f, FsPermission permission, EnumSet<CreateFlag> flag,
                                               int bufferSize, short replication, long blockSize, Progressable progress) throws IOException {
    if (needCheckPermission() && !checkAncestorAccess(f, FsAction.WRITE, "createNonRecursive")) {
      if (!flag.contains(CreateFlag.OVERWRITE) || !superGroupFileSystem.exists(f)) {
        return superGroupFileSystem.createNonRecursive(f, permission, flag, bufferSize, replication, blockSize, progress);
      } else if (!checkPathAccess(f, FsAction.WRITE, "createNonRecursive")) {
        return superGroupFileSystem.createNonRecursive(f, permission, flag, bufferSize, replication, blockSize, progress);
      }
    }
    statistics.incrementWriteOps(1);
    int fd = lib.jfs_create(Thread.currentThread().getId(), handle, normalizePath(f), permission.toShort(), uMask.toShort());
    while (fd == EEXIST) {
      if (!flag.contains(CreateFlag.OVERWRITE) || isDirectory(f)) {
        throw new FileAlreadyExistsException("File already exists: " + f);
      }
      delete(f, false);
      fd = lib.jfs_create(Thread.currentThread().getId(), handle, normalizePath(f), permission.toShort(), uMask.toShort());
    }
    if (fd < 0) {
      throw error(fd, makeQualified(f).getParent());
    }
    return createFsDataOutputStream(f, bufferSize, fd, 0L);
  }

  private FSDataOutputStream createFsDataOutputStream(Path f, int bufferSize, int fd, long startPosition) throws IOException {
    FSOutputStream out = new FSOutputStream(fd, f);
    if (withStreamCapability) {
      try {
        return new FSDataOutputStream(
                (OutputStream) constructor.newInstance(out, checkBufferSize(bufferSize), hflushMethod), statistics, startPosition);
      } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
        throw new RuntimeException(e);

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Pass overwrite=true or add CreateFlag.OVERWRITE if replacing the file is intended
  2. Delete the existing file before create
  3. Generate unique file names per attempt/task
  4. Catch FileAlreadyExistsException to implement open-if-exists logic

Example fix

// before
FSDataOutputStream out = fs.create(path, false);
// after
FSDataOutputStream out = fs.create(path, true); // or delete first
Defensive patterns

Strategy: try-catch

Validate before calling

if (fs.exists(path)) { /* delete or choose new name before create */ }

Try / catch

try { return fs.create(path, false); } catch (FileAlreadyExistsException e) { /* reuse existing file or delete and recreate */ return fs.open(path); }

Prevention

When it happens

Trigger: create(f, overwrite=false) on an existing file; create with CreateFlag.CREATE only on an existing path; create on an existing directory path; racing create calls to the same path.

Common situations: Idempotent writers expecting create to succeed silently; task retries writing the same output file; passing a directory path where a file is expected; Kafka/HBase exporters with fixed file names.

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 juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/e233da5e031d23cb. Report an issue: GitHub.