apache/hadoop · error · FileAlreadyExistsException
Parent path is not a directory: {} {}
Error message
Parent path is not a directory: {} {} What it means
FileAlreadyExistsException from unprotectedMkdir: while creating missing ancestors during mkdir -p, an existing component of the parent chain is a file rather than a directory. The message names the offending parent path plus the child component it tried to create beneath it.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirMkdirOp.java:220
p.getUserAction().or(FsAction.WRITE_EXECUTE),
p.getGroupAction(),
p.getOtherAction()), p.getUnmasked());
}
return new PermissionStatus(perm.getUserName(), perm.getGroupName(),
ancestorPerm);
}
/**
* create a directory at path specified by parent
*/
private static INodesInPath unprotectedMkdir(FSDirectory fsd, long inodeId,
INodesInPath parent, byte[] name, PermissionStatus permission,
List<AclEntry> aclEntries, long timestamp)
throws QuotaExceededException, AclException, FileAlreadyExistsException {
assert fsd.hasWriteLock();
assert parent.getLastINode() != null;
if (!parent.getLastINode().isDirectory()) {
throw new FileAlreadyExistsException("Parent path is not a directory: " +
parent.getPath() + " " + DFSUtil.bytes2String(name));
}
final INodeDirectory dir = new INodeDirectory(inodeId, name, permission,
timestamp);
INodesInPath iip = fsd.addLastINode(parent, dir, permission.getPermission(),
true, Optional.empty());
if (iip != null && aclEntries != null) {
AclStorage.updateINodeAcl(dir, aclEntries, Snapshot.CURRENT_STATE_ID);
}
return iip;
}
}
View on GitHub (pinned to 2add963021)
Solutions
- Walk the path level by level with `hdfs dfs -ls` to find the file component, then remove or rename it.
- Restructure paths so files never sit where directories are expected.
- Pre-validate all existing ancestors in code before calling mkdir -p.
Example fix
# before hdfs dfs -mkdir -p /etl/daily/2026/08/22 # FileAlreadyExistsException: Parent path is not a directory: /etl/daily 2026 # after hdfs dfs -mv /etl/daily /etl/daily.bak # move the blocking file hdfs dfs -mkdir -p /etl/daily/2026/08/22
Defensive patterns
Strategy: validation
Validate before calling
static void verifyAncestorsAreDirs(FileSystem fs, Path p) throws IOException {
for (Path cur = p.getParent(); cur != null && !cur.isRoot(); cur = cur.getParent()) {
if (fs.exists(cur) && !fs.getFileStatus(cur).isDirectory()) {
throw new ParentNotDirectoryException("File blocks the path at " + cur);
}
}
}
verifyAncestorsAreDirs(fs, p);
fs.mkdirs(p); Try / catch
try {
fs.mkdirs(p);
} catch (FileAlreadyExistsException e) {
// message names the offending parent component; surface it to the user
throw e;
} Prevention
- Never let files and directories share the same path prefix at different times.
- Validate the whole ancestor chain before deep mkdir -p in provisioning code.
When it happens
Trigger: `hdfs dfs -mkdir -p /part-file/a/b` where /part-file is a regular file; any deep mkdir where an intermediate component (not necessarily the last) is a file.
Common situations: Path templates where an earlier job wrote a file at a component now used as a directory (e.g., /etl/daily being both a file and a directory at different times); near-duplicate paths from case or trailing-space mismatches.
Related errors
- Mkdirs failed to create {} (exists={}, cwd={})
- parent is not a dir
- Parent path is not a directory: " + parent
- No such file or directory
- Input/output error
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/5ece3e6f0104d4a1.
Report an issue: GitHub.