apache/hadoop · error · PathIsNotDirectoryException

{}

Error message

{}

What it means

INodeDirectory.valueOf throws PathIsNotDirectoryException when the path resolves to an INode that exists but is not a directory (a regular file or symlink). HDFS uses this distinct exception type so callers can separate 'missing path' from 'wrong kind of path' — it maps to a client-side 'Not a directory' error.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/INodeDirectory.java:65

import org.apache.hadoop.security.AccessControlException;

import static org.apache.hadoop.hdfs.protocol.HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;

/**
 * Directory INode class.
 */
public class INodeDirectory extends INodeWithAdditionalFields
    implements INodeDirectoryAttributes {

  /** Cast INode to INodeDirectory. */
  public static INodeDirectory valueOf(INode inode, Object path
      ) throws FileNotFoundException, PathIsNotDirectoryException {
    if (inode == null) {
      throw new FileNotFoundException("Directory does not exist: "
          + DFSUtil.path2String(path));
    }
    if (!inode.isDirectory()) {
      throw new PathIsNotDirectoryException(DFSUtil.path2String(path));
    }
    return inode.asDirectory(); 
  }

  // Profiling shows that most of the file lists are between 1 and 4 elements.
  // Thus allocate the corresponding ArrayLists with a small initial capacity.
  public static final int DEFAULT_FILES_PER_DIRECTORY = 2;

  static final byte[] ROOT_NAME = DFSUtil.string2Bytes("");

  private List<INode> children = null;
  
  /** constructor */
  public INodeDirectory(long id, byte[] name, PermissionStatus permissions,
      long mtime) {
    super(id, name, permissions, mtime, 0L);
  }
  

View on GitHub (pinned to 2add963021)

Solutions

  1. Check FileStatus/isDirectory() first and use the correct path
  2. If the location must be a directory, move or delete the conflicting file (verify ownership of the data first)
  3. Catch PathIsNotDirectoryException explicitly and surface a precise error to the client instead of a generic failure

Example fix

// before
INodeDirectory dir = INodeDirectory.valueOf(node, path); // path is a file -> throws

// after
if (!node.isDirectory()) {
  throw new PathIsNotDirectoryException(DFSUtil.path2String(path));
}
INodeDirectory dir = INodeDirectory.valueOf(node, path);
Defensive patterns

Strategy: type-guard

Validate before calling

// Client-side: stat before using a path as a directory
FileStatus st = fs.getFileStatus(path);
if (!st.isDirectory()) {
  throw new IllegalArgumentException("Expected directory, got file/symlink: " + path);
}

Type guard

boolean isUsableDirectory(FileSystem fs, Path p) throws IOException {
  FileStatus st = fs.getFileStatus(p);
  return st.isDirectory();   // false for files and symlinks
}

Try / catch

catch (PathIsNotDirectoryException e) {
  // wrong-kind path: fix the path or fail with a precise message; not retryable
  throw new IllegalArgumentException(e.getPath() + " must be a directory", e);
}

Prevention

When it happens

Trigger: Passing a file path where the code requires a directory (e.g. rename destination parent is a file); internal listing/quota operations on a path occupied by a file; a symlink where the caller did not resolve the target.

Common situations: Path-building bugs where an earlier step created the component as a file; applications that store data at a path later reused as a directory; tools that do not follow symlinks.

Related errors


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