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
- Ensure hadoop-common is on the runtime classpath ('hadoop classpath' includes it).
- Check for shading/relocation of org.apache.hadoop.fs classes in deployed jars.
- Run inside a Hadoop environment (hadoop jar / YARN) rather than a bare JVM.
- 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
- Always launch via 'hadoop jar' or include 'hadoop classpath' on the JVM classpath.
- Avoid uber-jars that shade org.apache.hadoop classes.
- Verify with a smoke test job before production rollout.
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
- Compression codec not found:
- incompatible hadoop version
- construct fileStatus failed
- name is required
- Invalid start or len parameter
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/89d51f5fddc1998d.
Report an issue: GitHub.