apache/hadoop · error · FileAlreadyExistsException

Can't make directory for path '%s', it is a file.

Error message

Can't make directory for path '%s', it is a file.

What it means

Before creating directories, validatePath walks every ancestor of the requested path; if any ancestor exists as a FILE it throws FileAlreadyExistsException naming that ancestor. This is the object-store equivalent of POSIX ENOTDIR: a directory cannot be created beneath something that is a file. The check walks upward until it finds an existing directory or the root.

Source

Thrown at hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNFileSystem.java:493

  /**
   * Validate the path from the bottom up.
   *
   * @param path The path to be validated
   * @throws FileAlreadyExistsException The specified path is an existing file
   * @throws IOException                Getting the file status of the
   *                                    specified path occurs
   *                                    an IOException.
   */
  private void validatePath(Path path) throws IOException {
    Path parent = path.getParent();
    do {
      try {
        FileStatus fileStatus = getFileStatus(parent);
        if (fileStatus.isDirectory()) {
          break;
        } else {
          throw new FileAlreadyExistsException(String.format(
              "Can't make directory for path '%s', it is a file.", parent));
        }
      } catch (FileNotFoundException e) {
        LOG.debug("The Path: [{}] does not exist.", path);
      }
      parent = parent.getParent();
    } while (parent != null);
  }

  @Override
  public boolean mkdirs(Path f, FsPermission permission) throws IOException {
    try {
      FileStatus fileStatus = getFileStatus(f);
      if (fileStatus.isDirectory()) {
        return true;
      } else {
        throw new FileAlreadyExistsException("Path is a file: " + f);
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Locate the offending ancestor (the message names it) and delete or rename it.
  2. Stop reusing a former file path as a directory level; choose a non-colliding layout.
  3. Retry fs.mkdirs after the conflict is removed.

Example fix

// before
fs.mkdirs(new Path('/data/dt=2026-08-22/hour=00')); // FileAlreadyExistsException: Can't make directory for path '/data/dt=2026-08-22', it is a file.

// after
Path conflicting = new Path('/data/dt=2026-08-22');
if (fs.exists(conflicting) && fs.getFileStatus(conflicting).isFile()) {
  fs.delete(conflicting, false);
}
fs.mkdirs(new Path('/data/dt=2026-08-22/hour=00'));
Defensive patterns

Strategy: validation

Validate before calling

for (Path anc = f.getParent(); anc != null; anc = anc.getParent()) {
  if (!fs.exists(anc)) { break; } // everything above will be created
  if (fs.getFileStatus(anc).isFile()) {
    throw new IllegalStateException('Ancestor exists as a file: ' + anc);
  }
}

Try / catch

try {
  fs.mkdirs(f);
} catch (FileAlreadyExistsException e) {
  // message names the offending ancestor; surface it to the operator
  throw new IllegalStateException('Conflicting file in path chain: ' + e.getMessage(), e);
}

Prevention

When it happens

Trigger: fs.mkdirs('/a/b/c') where '/a' or '/a/b' already exists as a file object; chained directory creation after an earlier create() wrote a file at a level now needed as a directory.

Common situations: Path layout changed between runs (yesterday /dt=2026 was a file, today /dt=2026/hour=00 needs it as a directory); a partition value collides with an existing file; stale files left by aborted jobs or schema evolution.

Related errors


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