elastic/elasticsearch · critical · IllegalStateException
%s requires Java %s:, your system: %s
Error message
%s requires Java %s:, your system: %s
What it means
Thrown by JarHell.checkJavaVersion when a JAR's manifest declares an 'X-Compile-Target-JDK' attribute whose Java feature version is higher than the running JVM's feature version. Elasticsearch scans every JAR on the classpath at startup and refuses to boot if any JAR requires a newer JDK than the one running. The comparison is purely on the feature number (e.g. 21 vs 17), not the full version string.
Source
Thrown at libs/core/src/main/java/org/elasticsearch/jdk/JarHell.java:280
}
/** inspect manifest for sure incompatibilities */
private static void checkManifest(Manifest manifest, Path jar) {
// give a nice error if jar requires a newer java version
String targetVersion = manifest.getMainAttributes().getValue("X-Compile-Target-JDK");
if (targetVersion != null) {
checkJavaVersion(jar.toString(), targetVersion);
}
}
/**
* Checks that the java specification version {@code targetVersion}
* required by {@code resource} is compatible with the current installation.
*/
public static void checkJavaVersion(String resource, String targetVersion) {
Version version = Version.parse(targetVersion);
if (Runtime.version().feature() < version.feature()) {
throw new IllegalStateException(
String.format(Locale.ROOT, "%s requires Java %s:, your system: %s", resource, targetVersion, Runtime.version().toString())
);
}
}
private static void checkClass(Map<String, Path> clazzes, String clazz, Path jarpath) {
if (clazz.equals("module-info") || clazz.endsWith(".module-info")) {
// Ignore jigsaw module descriptions
return;
}
Path previous = clazzes.put(clazz, jarpath);
if (previous != null) {
if (previous.equals(jarpath)) {
// throw a better exception in this ridiculous case.
// unfortunately the zip file format allows this buggy possibility
// UweSays: It can, but should be considered as bug :-)
throw new IllegalStateException(
"jar hell!"View on GitHub (pinned to db6a809a66)
Solutions
- Upgrade the runtime JDK to a feature version >= the one named in the error message (e.g. install JDK 21 if the JAR requires Java 21).
- Verify JAVA_HOME and PATH resolve to the intended JDK: run 'java -version' as the ES user.
- Rebuild or reinstall the offending JAR/plugin against the JDK you actually run, so its X-Compile-Target-JDK manifest attribute matches.
- If the JAR is third-party, replace it with a build compiled for your target JDK feature level.
Example fix
// before: running on JDK 17 with a JAR requiring 21 // java -version -> 17.0.x // after: install and select JDK 21+ export JAVA_HOME=/path/to/jdk-21 bin/elasticsearch
Defensive patterns
Strategy: validation
Validate before calling
// Before scanning/launching, verify the runtime meets every JAR's requirement
import java.lang.Runtime;
import java.util.jar.*;
void assertJdkCompatible(List<Path> jars) throws IOException {
int runtimeFeature = Runtime.version().feature();
for (Path jar : jars) {
try (var f = new JarFile(jar.toFile())) {
var v = f.getManifest().getMainAttributes().getValue("X-Compile-Target-JDK");
if (v != null && Runtime.version().parse(v).feature() > runtimeFeature) {
throw new IllegalStateException(jar + " requires Java " + v);
}
}
}
} Prevention
- Pin JAVA_HOME to a JDK feature version >= the maximum declared X-Compile-Target-JDK across all classpath jars.
- In CI, assert 'java -version' feature >= the project's source/target before launching ES.
- Validate plugin jars against the running JDK before installing them into a node.
When it happens
Trigger: A JAR on the classpath (class dir, module jar, or plugin jar) has a MANIFEST.MF with 'X-Compile-Target-JDK: <version>' where the numeric feature is greater than Runtime.version().feature(). Triggered during checkManifest() which is called from the jar-hell scan loop iterating over every classpath element.
Common situations: Running Elasticsearch built for JDK 21 on a JDK 17 runtime; installing a plugin compiled against a newer JDK onto an older node; CI using JAVA_HOME pointing at an older toolchain than the build expected; downgrading the JVM after building.
Related errors
- Classpath should not contain empty elements! (outdated shell
- jar hell! duplicate jar [{element}] on classpath: {classPath
- jar hell! duplicate jar on classpath: {path}
- jar hell! class: {clazz} exists multiple times in jar: {jarp
- jar hell! class: {clazz} jar1: {previous} jar2: {jarpath}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/4bbec7165249a3cf.
Report an issue: GitHub.