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

  1. 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).
  2. Verify JAVA_HOME and PATH resolve to the intended JDK: run 'java -version' as the ES user.
  3. Rebuild or reinstall the offending JAR/plugin against the JDK you actually run, so its X-Compile-Target-JDK manifest attribute matches.
  4. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/4bbec7165249a3cf. Report an issue: GitHub.