apache/hadoop · error · FileNotFoundException

Path points to dir not a file

Error message

Path points to dir not a file

What it means

ViewFileSystem.InternalDir.getFileBlockLocations(...) serves paths that resolve to mount-table internal directories. If the path is exactly the internal dir (checkPathIsSlash) and no root fallback link exists to forward to, the location of a 'file' cannot be computed because the path is a directory node of the mount table; it throws FileNotFoundException('Path points to dir not a file').

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java:1524

      // When application calls listFiles on internalDir, it would return
      // RemoteIterator from InternalDirOfViewFs. If there is a fallBack, there
      // is a chance of files exists under that internalDir in fallback.
      // Iterator#next will call getFileBlockLocations with that files. So, we
      // should return getFileBlockLocations on fallback. See HDFS-15532.
      if (!InodeTree.SlashPath.equals(fs.getPath()) && this.fsState
          .getRootFallbackLink() != null) {
        FileSystem linkedFallbackFs =
            this.fsState.getRootFallbackLink().getTargetFileSystem();
        Path parent = Path.getPathWithoutSchemeAndAuthority(
            new Path(theInternalDir.fullPath));
        Path pathToFallbackFs = new Path(parent, fs.getPath().getName());
        return linkedFallbackFs
            .getFileBlockLocations(pathToFallbackFs, start, len);
      }

      checkPathIsSlash(fs.getPath());
      throw new FileNotFoundException("Path points to dir not a file");
    }

    @Override
    public FileChecksum getFileChecksum(final Path f)
        throws FileNotFoundException, IOException {
      checkPathIsSlash(f);
      throw new FileNotFoundException("Path points to dir not a file");
    }

    @Override
    public FileStatus getFileStatus(Path f) throws IOException {
      checkPathIsSlash(f);
      return new FileStatus(0, true, 0, 0, creationTime, creationTime,
          PERMISSION_555, ugi.getShortUserName(), ugi.getPrimaryGroupName(),
          new Path(theInternalDir.fullPath).makeQualified(
              myUri, ROOT_PATH));
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Point the input path at the mounted child directory or at files beneath it
  2. Add fs.viewfs.mounttable.default.linkMergeSlash or a linkFallback for that internal dir so locations delegate to a real file system
  3. List the internal dir and recurse into mounted children instead of asking locations for the dir itself
  4. Validate with getFileStatus(path).isDirectory() before requesting block locations and skip directories

Example fix

// before
FileStatus st = fs.getFileStatus(new Path("/data"));
BlockLocation[] locs = fs.getFileBlockLocations(st, 0, st.getLen()); // dir -> throws

// after
if (fs.getFileStatus(new Path("/data")).isDirectory()) {
  for (FileStatus child : fs.listStatus(new Path("/data"))) {
    if (child.isFile()) { /* ask locations per file */ }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Only request block locations for regular files
FileStatus st = fs.getFileStatus(p);
if (st.isDirectory()) {
  throw new IllegalArgumentException(p + " is a directory; no block locations");
}
BlockLocation[] locs = fs.getFileBlockLocations(st, 0, st.getLen());

Try / catch

try {
  locs = fs.getFileBlockLocations(st, start, len);
} catch (FileNotFoundException e) {
  // mount-table internal dir: recurse into mounted children instead
  locs = new BlockLocation[0];
}

Prevention

When it happens

Trigger: Split computation (FileInputFormat/FileSplit) or any getFileBlockLocations call on a viewfs path that is an internal mount-table directory, e.g. '/data' when only /data/hdfs is mounted; distcp or readers asking block locations for the parent of mounts.

Common situations: MapReduce/Spark input paths set to a viewfs internal dir without linkMergeSlash; recursive listings where a parent dir is fed to a block-location API; federation migrations where the old input root became a virtual directory.

Related errors


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