juicedata/juicefs · error · IOException
construct fileStatus failed
Error message
construct fileStatus failed
What it means
Raised while building a FileStatus via reflection when the 13-arg constructor (with ACL fields, used on newer Hadoop versions) throws. JuiceFS tries a Hadoop-3.x-specific FileStatus constructor first; if instantiation fails (signature mismatch or inner error) it wraps the cause in an IOException.
Source
Thrown at sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java:1778
boolean isdir = ((mode >>> 31) & 1) == 1; // Go
int stickybit = (mode >>> 20) & 1;
boolean hasAcl = (mode >> 18 & 1) == 1;
FsPermission perm = new FsPermission((short) ((mode & 0777) | (stickybit << 9)));
perm = new FsPermissionExtension(perm, hasAcl, false);
long length = buf.getLongLong(4);
long mtime = buf.getLongLong(12);
long atime = buf.getLongLong(20);
String user = buf.getString(28);
String group = buf.getString(28 + user.length() + 1);
assert (30 + user.length() + group.length() == size);
if (fileStatusConstructor == null) {
return new FileStatus(length, isdir, 1, blocksize, mtime, atime, perm, user, group, p);
} else {
try {
return fileStatusConstructor.newInstance(length, isdir, 1, blocksize, mtime, atime, perm, user, group, null, p, hasAcl, false, false);
} catch (Exception e) {
throw new IOException("construct fileStatus failed", e);
}
}
}
@Override
public FileStatus[] listStatus(Path f) throws IOException {
if (needCheckPermission() && !checkPathAccess(f, FsAction.READ_EXECUTE, "listStatus")) {
return superGroupFileSystem.listStatus(f);
}
statistics.incrementReadOps(1);
int bufsize = 32 << 10;
Pointer buf = Memory.allocate(Runtime.getRuntime(lib), bufsize); // TODO: smaller buff
String path = normalizePath(f);
int r = lib.jfs_listdir(Thread.currentThread().getId(), handle, path, 0, buf, bufsize);
if (r == ENOENT) {
throw new FileNotFoundException(f.toString());
}
if (r == ENOTDIR) {View on GitHub (pinned to c9a67b23e8)
Solutions
- Align the JuiceFS Hadoop SDK version with the cluster's Hadoop version
- Check the wrapped cause (getCause()) to see the real constructor failure
- Ensure no conflicting/shaded org.apache.hadoop classes shadow the real ones
- Report upstream if the constructor resolution logic needs to cover your Hadoop version
Example fix
// pom.xml before <hadoop.version>2.7.3</hadoop.version> // after — match deployment cluster <hadoop.version>3.3.4</hadoop.version>
Defensive patterns
Strategy: try-catch
Validate before calling
// verify Hadoop version: org.apache.hadoop.util.VersionInfo.getVersion() matches your SDK build
Try / catch
try { FileStatus st = getFileStatus(path); } catch (IOException e) { if (e.getMessage().equals("construct fileStatus failed")) { log.error("Hadoop version mismatch", e.getCause()); } throw e; } Prevention
- Match the juicefs-hadoop jar to the cluster Hadoop major version
- Inspect getCause() for the reflective instantiation error
- Avoid shaded Hadoop classes on the classpath
- Test listStatus/getFileStatus after any Hadoop upgrade
When it happens
Trigger: Running against a Hadoop version whose FileStatus constructor signature differs from what was resolved reflectively; the resolved constructor throws while validating arguments (e.g. null path or permission incompatible with the Hadoop build).
Common situations: Hadoop-version mismatch: jar built/tested against Hadoop 2 but deployed on Hadoop 3 (or vice versa) so reflective resolution picks a wrong constructor; shaded/relocated Hadoop classes on the classpath.
Related errors
- Compression codec not found:
- incompatible hadoop version
- Hadoop version was incompatible, current hadoop version is:\
- Invalid start or len parameter
- stream was closed
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/659d019a90d6b7a9.
Report an issue: GitHub.