apache/hadoop · error · IllegalArgumentException
PathHandle only available for files
Error message
PathHandle only available for files
What it means
Thrown by RawLocalFileSystem.createPathHandle (the hook behind FileSystem.getPathHandle(FileStatus, HandleOpt...)) when the supplied FileStatus refers to a directory or a symbolic link. A PathHandle is an immutable reference to the *content* of a regular file, so directories and links have no meaningful handle in the local FileSystem implementation. The library fails fast with IllegalArgumentException rather than returning a handle that could never be resolved.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java:1233
pathToFile(p).toPath(), BasicFileAttributeView.class);
FileTime fmtime = (mtime >= 0) ? FileTime.fromMillis(mtime) : null;
FileTime fatime = (atime >= 0) ? FileTime.fromMillis(atime) : null;
view.setTimes(fmtime, fatime, null);
} catch (NoSuchFileException e) {
throw new FileNotFoundException("File " + p + " does not exist");
}
}
/**
* Hook to implement support for {@link PathHandle} operations.
* @param stat Referent in the target FileSystem
* @param opts Constraints that determine the validity of the
* {@link PathHandle} reference.
*/
protected PathHandle createPathHandle(FileStatus stat,
Options.HandleOpt... opts) {
if (stat.isDirectory() || stat.isSymlink()) {
throw new IllegalArgumentException("PathHandle only available for files");
}
String authority = stat.getPath().toUri().getAuthority();
if (authority != null && !authority.equals("file://")) {
throw new IllegalArgumentException("Wrong FileSystem: " + stat.getPath());
}
Options.HandleOpt.Data data =
Options.HandleOpt.getOpt(Options.HandleOpt.Data.class, opts)
.orElse(Options.HandleOpt.changed(false));
Options.HandleOpt.Location loc =
Options.HandleOpt.getOpt(Options.HandleOpt.Location.class, opts)
.orElse(Options.HandleOpt.moved(false));
if (loc.allowChange()) {
throw new UnsupportedOperationException("Tracking file movement in " +
"basic FileSystem is not supported");
}
final Path p = stat.getPath();
final Optional<Long> mtime = !data.allowChange()
? Optional.of(stat.getModificationTime())View on GitHub (pinned to 2add963021)
Solutions
- Filter to regular files first: only call getPathHandle when stat.isFile() && !stat.isSymlink()
- If the referent is a symlink to a file, resolve the link target (fs.resolvePath/stat via FileContext) and build the handle from the target's FileStatus
- Catch IllegalArgumentException at the call site and skip the entry when iterating heterogeneous listings
Example fix
// before
FileStatus st = localFs.getFileStatus(p);
PathHandle h = localFs.getPathHandle(st);
// after
FileStatus st = localFs.getFileStatus(p);
if (st.isDirectory() || st.isSymlink()) {
throw new IllegalArgumentException("PathHandle requires a regular file: " + p);
}
PathHandle h = localFs.getPathHandle(st); Defensive patterns
Strategy: validation
Validate before calling
FileStatus st = fs.getFileStatus(p);
if (st.isDirectory() || st.isSymlink()) {
// skip or fail before asking for a handle
throw new IllegalArgumentException("PathHandle requires a regular file: " + p);
}
PathHandle h = fs.getPathHandle(st, opts); Try / catch
try {
PathHandle h = fs.getPathHandle(stat);
} catch (IllegalArgumentException e) {
// message: "PathHandle only available for files" -> wrong referent kind
log.warn("Skipping non-file: {}", stat.getPath());
} Prevention
- Always filter listings to stat.isFile() && !stat.isSymlink() before handle creation
- Treat getPathHandle arguments as coming from exactly one FileSystem listing
When it happens
Trigger: Calling localFs.getPathHandle(stat, opts) where stat was obtained via getFileStatus()/listStatus() on a directory, or on a symlink (stat.isSymlink() == true). Also hit when code takes FileStatus from listStatus() of a directory tree and blindly calls getPathHandle() on each entry.
Common situations: Batch tools iterating a directory and requesting handles for every entry without filtering; passing a link status returned by getFileLinkStatus(); test code that uses a temp directory instead of a temp file.
Related errors
- Wrong FileSystem: " + stat.getPath()
- Tracking file movement in basic FileSystem is not supported
- Unable to create symlink to non-local file system: " + targe
- Checksum file not a length multiple of checksum size in {} a
- Checksum error: {} at {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/be11ad904f18d8b7.
Report an issue: GitHub.