juicedata/juicefs · error · IllegalStateException

Hadoop version was incompatible, current hadoop version is:\

Error message

Hadoop version was incompatible, current hadoop version is:\t" + VersionInfo.getVersion()

What it means

initializeStorageIds() reflectively loads org.apache.hadoop.fs.BlockLocation and its setStorageIds(String[]) method. If the class itself is missing from the classpath (a Hadoop that old cannot be supported at all), an IllegalStateException is thrown naming the current Hadoop version. A missing method is tolerated (setStorageIds = null).

Source

Thrown at sdk/java/src/main/java/io/juicefs/JuiceFileSystemImpl.java:738

  private void updateUidAndGrouping(String uidFile, String groupFile) throws IOException {
    String uidstr = parseUidAndGrouping(USERNAME_UID_PATTERN, uidFile);
    if (uidstr == null && uidFile != null && !"".equals(uidFile.trim())) {
      uidstr = readFile(uidFile);
    }
    String grouping = parseUidAndGrouping(GROUPNAME_GID_USERNAMES_PATTERN, groupFile);
    if (grouping == null && groupFile != null && !"".equals(groupFile.trim())) {
      grouping = readFile(groupFile);
    }

    lib.jfs_update_uid_grouping(name, uidstr, grouping);
  }

  private void initializeStorageIds(Configuration conf) throws IOException {
    try {
      Class<?> clazz = Class.forName("org.apache.hadoop.fs.BlockLocation");
      setStorageIds = clazz.getMethod("setStorageIds", String[].class);
    } catch (ClassNotFoundException e) {
      throw new IllegalStateException(
              "Hadoop version was incompatible, current hadoop version is:\t" + VersionInfo.getVersion());
    } catch (NoSuchMethodException e) {
      setStorageIds = null;
    }
    int vdiskPerCpu = Integer.parseInt(getConf(conf, "vdisk-per-cpu", "4"));
    storageIds = new String[java.lang.Runtime.getRuntime().availableProcessors() * vdiskPerCpu];
    for (int i = 0; i < storageIds.length; i++) {
      storageIds[i] = "vd" + i;
    }
  }

  @Override
  public Path getHomeDirectory() {
    return makeQualified(new Path(homeDirPrefix + "/" + user));
  }

  private static void initStubLoader() {
    int loadMaxTime = 30;

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Ensure hadoop-common is on the runtime classpath ('hadoop classpath' includes it).
  2. Check for shading/relocation of org.apache.hadoop.fs classes in deployed jars.
  3. Run inside a Hadoop environment (hadoop jar / YARN) rather than a bare JVM.
  4. If it persists, log VersionInfo.getVersion() output and align the client jar with the cluster version.

Example fix

// before
java -cp juicefs-hadoop.jar App  # no hadoop-common -> IllegalStateException
// after
hadoop jar app.jar App  # or: -cp "$(hadoop classpath):juicefs-hadoop.jar"
Defensive patterns

Strategy: validation

Validate before calling

try {
  Class.forName("org.apache.hadoop.fs.BlockLocation");
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("hadoop-common missing from classpath: "
      + System.getProperty("java.class.path"));
}

Try / catch

try { fs = FileSystem.get(uri, conf); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Hadoop version was incompatible")) { /* fix classpath / run under hadoop jar */ } throw e; }

Prevention

When it happens

Trigger: Class.forName("org.apache.hadoop.fs.BlockLocation") throws ClassNotFoundException during initializeStorageIds() — effectively never in any real Hadoop, indicating BlockLocation is shaded/absent from the runtime classpath.

Common situations: Shaded/uber jars that exclude or relocate org.apache.hadoop classes; running the client outside Hadoop with only a partial classpath; classloader isolation (e.g. separate user classpath) hiding hadoop-common.

Related errors


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