apache/hadoop · error · FileNotFoundException

Path is not a file: {}

Error message

Path is not a file: {}

What it means

INodeFile.valueOf throws FileNotFoundException("Path is not a file: <path>") when the path exists but resolves to something other than a regular file — typically a directory, or a symlink. Note that HDFS deliberately reuses FileNotFoundException for this wrong-type case, so the message (not the class) distinguishes it from a truly missing file.

Source

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

  /** The same as valueOf(inode, path, false). */
  public static INodeFile valueOf(INode inode, String path
      ) throws FileNotFoundException {
    return valueOf(inode, path, false);
  }

  /** Cast INode to INodeFile. */
  public static INodeFile valueOf(INode inode, String path, boolean acceptNull)
      throws FileNotFoundException {
    if (inode == null) {
      if (acceptNull) {
        return null;
      } else {
        throw new FileNotFoundException("File does not exist: " + path);
      }
    }
    if (!inode.isFile()) {
      throw new FileNotFoundException("Path is not a file: " + path);
    }
    return inode.asFile();
  }

  /** 
   * Bit format:
   * [4-bit storagePolicyID][12-bit BLOCK_LAYOUT_AND_REDUNDANCY]
   * [48-bit preferredBlockSize]
   *
   * BLOCK_LAYOUT_AND_REDUNDANCY contains 12 bits and describes the layout and
   * redundancy of a block. We use the highest 1 bit to determine whether the
   * block is replica or erasure coded. For replica blocks, the tail 11 bits
   * stores the replication factor. For erasure coded blocks, the tail 11 bits
   * stores the EC policy ID, and in the future, we may further divide these
   * 11 bits to store both the EC policy ID and replication factor for erasure
   * coded blocks. The layout of this section is demonstrated as below.
   *
   * Another possible future extension is for future block types, in which case

View on GitHub (pinned to 2add963021)

Solutions

  1. Check inode.isFile() / FileStatus.isFile() first and branch or fix the path
  2. Correct the path construction (missing filename component, wrong separator)
  3. When catching, inspect the message ('Path is not a file') to distinguish wrong-type from missing

Example fix

// before
INodeFile f = INodeFile.valueOf(node, path); // path is a directory -> throws

// after
if (!node.isFile()) {
  throw new FileNotFoundException("Path is not a file: " + path);
}
INodeFile f = INodeFile.valueOf(node, path);
Defensive patterns

Strategy: type-guard

Validate before calling

// Client-side: confirm regular file before file-only APIs
FileStatus st = fs.getFileStatus(path);
if (!st.isFile()) {
  throw new IllegalArgumentException("Expected a file: " + path
      + " (isDirectory=" + st.isDirectory()
      + ", isSymlink=" + st.isSymlink() + ")");
}

Type guard

boolean isRegularFile(FileSystem fs, Path p) throws IOException {
  FileStatus st = fs.getFileStatus(p);
  return st.isFile() && !st.isSymlink();
}

Try / catch

catch (FileNotFoundException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Path is not a file")) {
    throw new IllegalArgumentException("Path is a directory or symlink: " + path, e);
  }
  throw e; // genuinely missing file
}

Prevention

When it happens

Trigger: Opening, appending to, or validating a path that is actually a directory; a symlink passed to a file-only API without following the link; path construction that dropped the final file component.

Common situations: Directories used as placeholders where code later expects a file; datasets addressed at directory roots while the client opens them as files; symlink-aware tools hitting raw links.

Related errors


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