apache/hadoop · error · ParentNotDirectoryException

rename destination parent ${parent} is a file.

Error message

rename destination parent ${parent} is a file.

What it means

The destination-parent check in the deprecated rename: the parent of dst exists but is a regular file, so ParentNotDirectoryException('rename destination parent parent is a file.') is thrown. Nothing can be renamed 'into' a file path.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileSystem.java:1719

      }
      // Delete the destination that is a file or an empty directory
      if (dstStatus.isDirectory()) {
        FileStatus[] list = listStatus(dst);
        if (list != null && list.length != 0) {
          throw new IOException(
              "rename cannot overwrite non empty destination directory " + dst);
        }
      }
      delete(dst, false);
    } else {
      final Path parent = dst.getParent();
      final FileStatus parentStatus = getFileStatus(parent);
      if (parentStatus == null) {
        throw new FileNotFoundException("rename destination parent " + parent
            + " not found.");
      }
      if (!parentStatus.isDirectory()) {
        throw new ParentNotDirectoryException("rename destination parent " + parent
            + " is a file.");
      }
    }
    if (!rename(src, dst)) {
      throw new IOException("rename from " + src + " to " + dst + " failed.");
    }
  }

  /**
   * Truncate the file in the indicated path to the indicated size.
   * <ul>
   *   <li>Fails if path is a directory.</li>
   *   <li>Fails if path does not exist.</li>
   *   <li>Fails if path is not closed.</li>
   *   <li>Fails if new size is greater than current size.</li>
   * </ul>
   * @param f The path to the file to be truncated
   * @param newLength The size the file is to be truncated to

View on GitHub (pinned to 2add963021)

Solutions

  1. Delete or relocate the file occupying the parent path (after verifying it is disposable)
  2. Adjust the destination naming to avoid the colliding prefix
  3. Pre-flight: assert every prefix of dst is a directory or absent

Example fix

// before
fs.rename(src, new Path("/out/part-0/x")); // /out/part-0 is a file

// after
Path dst = new Path("/out/part-0/x");
Path parent = dst.getParent();
if (fs.exists(parent) && !fs.getFileStatus(parent).isDirectory()) {
  fs.delete(parent, false);
  fs.mkdirs(parent);
}
fs.rename(src, dst);
Defensive patterns

Strategy: validation

Validate before calling

Path parent = dst.getParent();
if (fs.exists(parent) && !fs.getFileStatus(parent).isDirectory()) {
  throw new IllegalStateException("rename parent is a file: " + parent);
}
fs.rename(src, dst);

Prevention

When it happens

Trigger: rename(src, a/b/c) where a/b exists as a file - the destination prefix is occupied by a file.

Common situations: Stale marker/output files occupying directory prefixes; layouts where a path flips between file and directory across runs; partial cleanup leaving files behind.

Related errors


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