apache/hadoop · error · FileAlreadyExistsException
{} is a directory
Error message
{} is a directory What it means
RawFileSystem.create stats the target first; when an existing directory sits at the path it throws FileAlreadyExistsException('<path> is a directory'). This happens regardless of the overwrite flag, because removing a directory tree to satisfy a file create would destroy data.
Source
Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java:163
Preconditions.checkArgument(rangeSize > 0, "Object storage range size must be positive.");
FSInputStream fsIn = new ObjectMultiRangeInputStream(taskThreadPool, storage, path,
status.getLen(), rangeSize, status.checksum());
return new FSDataInputStream(fsIn);
}
public FSDataInputStream open(Path path, byte[] expectedChecksum, Range range) {
return new FSDataInputStream(
new ObjectRangeInputStream(storage, path, range, expectedChecksum));
}
@Override
public FSDataOutputStream create(Path path, FsPermission permission, boolean overwrite,
int bufferSize, short replication, long blockSize, Progressable progress) throws IOException {
FileStatus fileStatus = getFileStatusOrNull(path);
if (fileStatus != null) {
if (fileStatus.isDirectory()) {
throw new FileAlreadyExistsException(path + " is a directory");
}
if (!overwrite) {
throw new FileAlreadyExistsException(path + " already exists");
}
LOG.debug("Overwriting file {}", path);
}
if (MagicOutputStream.isMagic(path)) {
return new FSDataOutputStream(
new MagicOutputStream(this, storage, uploadThreadPool, getConf(), makeQualified(path)),
null);
} else {
ObjectOutputStream out =
new ObjectOutputStream(storage, uploadThreadPool, getConf(), makeQualified(path), true);
if (fileStatus == null && FuseUtils.fuseEnabled()) {
// The fuse requires the file to be visible when accessing getFileStatus once we createdView on GitHub (pinned to 2add963021)
Solutions
- Choose an output path or file name that does not collide with the directory
- Delete the directory explicitly with fs.delete(path, true) only when its removal is intended
- Guard with a status check before create and fail with a clear message
Example fix
// before
fs.create(new Path("/outputs/data"), true); // /outputs/data is a directory
// after
Path out = new Path("/outputs/data");
if (fs.exists(out) && fs.getFileStatus(out).isDirectory()) {
fs.delete(out, true); // deliberate removal
}
try (FSDataOutputStream os = fs.create(out, true)) {
... // write
} Defensive patterns
Strategy: validation
Validate before calling
FileStatus st = fs.getFileStatusOrNull(path);
if (st != null && st.isDirectory()) {
throw new FileAlreadyExistsException("Output path is a directory: " + path
+ "; pick a file name or delete the directory first");
} Type guard
static boolean canCreateFile(FileSystem fs, Path p) throws IOException {
FileStatus st = fs.getFileStatusOrNull(p);
return st == null || st.isFile();
} Try / catch
try {
return fs.create(path, overwrite);
} catch (FileAlreadyExistsException e) {
if (e.getMessage() != null && e.getMessage().endsWith("is a directory")) {
// overwrite cannot fix a directory: choose a new name or delete(dir, true) deliberately
} else {
throw e;
}
} Prevention
- Never configure output file paths that overlap input or table directories
- Check the target with getFileStatusOrNull before create
- Remember overwrite=true does not bypass the directory check
When it happens
Trigger: create(path, ..., overwrite=true) where path exists as a directory with or without children; a file name equal to an existing partition directory; output path configured to the same location as an input directory.
Common situations: Reusing an input directory as the job output; Hive external table locations overlapping plain file writes; leftover directories from previous runs sharing the intended file name.
Related errors
- {} already exists
- {} already exists
- / is not a file. The directory / already exist at: <theInter
- Not a directory: {}
- Path is a file: {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/bb7afb05aeb51666.
Report an issue: GitHub.