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

  1. Align the JuiceFS Hadoop SDK version with the cluster's Hadoop version
  2. Check the wrapped cause (getCause()) to see the real constructor failure
  3. Ensure no conflicting/shaded org.apache.hadoop classes shadow the real ones
  4. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/659d019a90d6b7a9. Report an issue: GitHub.