apache/hadoop · error · FileNotFoundException

{} : not a file in {}

Error message

{} : not a file in {}

What it means

open(Path, int) found a HarStatus entry, but it is a directory (hstatus.isDir()). Directories in a har are index-only constructs with no byte range in the part files, so no input stream can be produced and open fails with FileNotFoundException ('not a file').

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HarFileSystem.java:684

  /**
   * @return null since no checksum algorithm is implemented.
   */
  @Override
  public FileChecksum getFileChecksum(Path f, long length) {
    return null;
  }

  /**
   * Returns a har input stream which fakes end of 
   * file. It reads the index files to get the part 
   * file name and the size and start of the file.
   */
  @Override
  public FSDataInputStream open(Path f, int bufferSize) throws IOException {
    // get the fs DataInputStream for the underlying file
    HarStatus hstatus = getFileHarStatus(f);
    if (hstatus.isDir()) {
      throw new FileNotFoundException(f + " : not a file in " +
                archivePath);
    }
    return new HarFSDataInputStream(fs, new Path(archivePath, 
        hstatus.getPartName()),
        hstatus.getStartIndex(), hstatus.getLength(), bufferSize);
  }

  @Override
  protected PathHandle createPathHandle(FileStatus stat, HandleOpt... opts) {
    // har consistency managed through metadata cache
    // could extend HarMetaData to track more explicitly
    throw new UnsupportedOperationException();
  }

  @Override
  public FSDataInputStream open(PathHandle fd, int bufferSize)
      throws IOException {
    throw new UnsupportedOperationException();

View on GitHub (pinned to 2add963021)

Solutions

  1. Check fs.getFileStatus(p).isDirectory() before open and descend with listStatus instead
  2. If you meant to read members, list the directory and open each file entry
  3. Validate user-supplied paths up front with getFileStatus and fail with a clear message

Example fix

// before
FSDataInputStream in = fs.open(dirPathInHar); // FileNotFoundException: not a file

// after
if (fs.getFileStatus(dirPathInHar).isDirectory()) {
  for (FileStatus s : fs.listStatus(dirPathInHar)) {
    if (s.isFile()) read(fs.open(s.getPath()));
  }
}
Defensive patterns

Strategy: validation

Validate before calling

FileStatus st = fs.getFileStatus(p);
if (st.isDirectory()) {
  throw new IllegalArgumentException(p + " is a directory; open() requires a file in the archive");
}

Try / catch

try {
  in = fs.open(p, bufferSize);
} catch (FileNotFoundException e) {
  if (e.getMessage() != null && e.getMessage().contains("not a file")) {
    // p is a directory: descend with listStatus instead
  }
  throw e;
}

Prevention

When it happens

Trigger: fs.open(dir) on any archive directory — the archive root har://.../data.har/ itself or a directory entry returned by listStatus; also generic code that opens user-supplied paths without a type check.

Common situations: Traversal code that calls open on every listStatus result, including directories; CLI tools whose 'input file' argument resolves to a directory inside an archive.

Related errors


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