apache/hadoop · error · FileNotFoundException

File does not exist: {}

Error message

File does not exist: {}

What it means

INodeFile.valueOf(INode, String) throws FileNotFoundException("File does not exist: <path>") when the INode resolves to null and acceptNull is false (the one-arg overload hard-codes false). It is the internal cast helper for code paths that require an existing regular file; a null INode means the file was deleted or never existed.

Source

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

  /**
   * Erasure Coded striped blocks have replication factor of 1.
   */
  public static final short DEFAULT_REPL_FOR_STRIPED_BLOCKS = 1;

  /** 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

View on GitHub (pinned to 2add963021)

Solutions

  1. Handle FileNotFoundException as a normal 'file gone' signal — recreate the file or return not-found to the caller
  2. If a null result is acceptable at the call site (e.g. best-effort cleanup), use the three-arg overload valueOf(inode, path, true)
  3. Guard with an existence check only when you must distinguish races from genuine absence

Example fix

// before
INodeFile file = INodeFile.valueOf(inode, path); // null inode -> throws

// after
INodeFile file = INodeFile.valueOf(inode, path, /* acceptNull */ true);
if (file == null) {
  // file already gone: treat as success for idempotent delete-style flows
}
Defensive patterns

Strategy: validation

Validate before calling

// NN-side: when absence is a valid state, ask for null instead of an exception
INodeFile file = INodeFile.valueOf(fsDir.getINode(path, DirOp.READ), path, /*acceptNull*/ true);
if (file == null) {
  return; // already absent — idempotent no-op
}

Try / catch

catch (FileNotFoundException e) {
  // Distinguish by message: 'File does not exist' vs 'Path is not a file'
  if (e.getMessage() != null && e.getMessage().startsWith("File does not exist")) {
    return absentResult();   // treat as gone / 404
  }
  throw e;
}

Prevention

When it happens

Trigger: Resolving a deleted or never-created file through the single-arg valueOf; a concurrent delete between the client's existence check and the NameNode's processing; append/open flows on files removed by a cleanup job.

Common situations: Application retry loops racing with lifecycle/cleaner jobs; stale cached paths; idempotent writers assuming the file still exists.

Related errors


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