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

  1. Walk the path level by level with `hdfs dfs -ls` to find the file component, then remove or rename it.
  2. Restructure paths so files never sit where directories are expected.
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/5ece3e6f0104d4a1. Report an issue: GitHub.