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
- Pass overwrite=true or add CreateFlag.OVERWRITE if replacing the file is intended
- Delete the existing file before create
- Generate unique file names per attempt/task
- 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
- Pass overwrite=true only when replacement is intended
- Validate target is not a directory
- Use unique output names per task/retry
- Catch FileAlreadyExistsException for open-if-exists flows
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
- Path already exists: " + f
- Invalid start or len parameter
- stream was closed
- arguments: " + off + " " + len
- position is negative
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/e233da5e031d23cb.
Report an issue: GitHub.