apache/hadoop · error · FileNotFoundException
{path}
Error message
{path} What it means
While FSImageLoader walks a queried path component by component, it looks up the current inode id in dirmap (directory id → children array, built from the INODE_DIR section). A null result means that inode has no recorded children — it is a file, not a directory — so descending further is impossible and FileNotFoundException(path) is thrown. The oiv web server maps it to HTTP 404.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineImageViewer/FSImageLoader.java:566
long id = INodeId.ROOT_INODE_ID;
for (int offset = 0, next; offset < path.length(); offset = next) {
next = path.indexOf('/', offset + 1);
if (next == -1) {
next = path.length();
}
if (offset + 1 > next) {
break;
}
final String component = path.substring(offset + 1, next);
if (component.isEmpty()) {
continue;
}
final long[] children = dirmap.get(id);
if (children == null) {
throw new FileNotFoundException(path);
}
boolean found = false;
for (long cid : children) {
FsImageProto.INodeSection.INode child = fromINodeId(cid);
if (component.equals(child.getName().toStringUtf8())) {
found = true;
id = child.getId();
break;
}
}
if (!found) {
throw new FileNotFoundException(path);
}
}
return id;
}
View on GitHub (pinned to 2add963021)
Solutions
- Remove the extra components or trailing slash after the file path.
- Check the parent with op=GETFILESTATUS first and only descend when type is DIRECTORY.
- Fix the path-construction logic in the calling script or client.
Example fix
# before curl 'http://localhost:5978/webhdfs/v1/user/me/notes.txt/?op=LISTSTATUS' # -> 404 (notes.txt is a file, cannot be listed into) # after curl 'http://localhost:5978/webhdfs/v1/user/me/notes.txt?op=GETFILESTATUS'
Defensive patterns
Strategy: try-catch
Validate before calling
// before descending, confirm the parent is a directory in the image
String status = image.getFileStatus(parentPath); // throws if absent
if (!status.contains("\"type\":\"DIRECTORY\"")) { // JSON from GETFILESTATUS
throw new IllegalArgumentException(parentPath + " is a file; cannot list into it");
} Type guard
static boolean isDirectoryStatus(String fileStatusJson) {
return fileStatusJson != null && fileStatusJson.contains("\"type\":\"DIRECTORY\"");
} Try / catch
try {
return image.getFileStatus(path);
} catch (FileNotFoundException e) {
// 404 semantics: path absent, or a file used as an intermediate directory
// normalize the path (drop trailing '/') and GETFILESTATUS the parent to tell which
throw e;
} Prevention
- Never append a trailing '/' blindly; only directories get one.
- GETFILESTATUS the parent and check type == DIRECTORY before LISTSTATUS.
- URL-decode path components before debugging — %2F changes the outcome.
When it happens
Trigger: Querying a path that continues below a file: /user/me/notes.txt/child via op=GETFILESTATUS or LISTSTATUS, including the trailing-slash form /user/me/notes.txt/ produced by naive path joining.
Common situations: Scripts that append '/' to every path uniformly; joining parent+child where the parent turns out to be a file; expecting symlink-style traversal semantics in a static fsimage.
Related errors
- File does not exist: {}
- File {} does not exist.
- Param op must be specified.
- Invalid value for webhdfs parameter "op"
- Path: {path} should start with /webhdfs/v1
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/ff38d351686b2e19.
Report an issue: GitHub.