Java "UnsupportedClassVersionError" - Fix Java Version Mismatch in CI
A class was compiled targeting a newer bytecode version than the JVM running it supports. The runtime refuses to load it -- the build JDK and the run-time JDK do not match.
What this error means
Startup fails with UnsupportedClassVersionError: ... has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version ... up to 55.0. It is fully deterministic and tied to which JDK compiled vs which runs.
Error: LinkageError occurred while loading main class com.example.App
java.lang.UnsupportedClassVersionError: com/example/App has been compiled by a
more recent version of the Java Runtime (class file version 61.0), this version
of the Java Runtime only recognizes class file versions up to 55.0Common causes
Run-time JDK older than the build JDK
The code (or a dependency) was compiled with, say, JDK 17 (class file 61), but the runner executes it on JDK 11 (max 55), so the bytecode is too new to load.
A dependency built for a newer Java
A third-party jar targets a higher Java release than your runtime, producing the same error even when your own code targets an older release.
How to fix it
Align the runtime JDK with the build target
- Decide the target Java release and set it consistently for compile and run.
- Use the same JDK major version in setup-java that the build targets.
- Confirm
java -versionon the runner matches the compiled class file version.
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- run: java -version && java -jar app.jarLower the compile target instead
If the runtime cannot be upgraded, build for the older release with the toolchain or release flag.
// build.gradle
java {
toolchain { languageVersion = JavaLanguageVersion.of(11) }
}How to prevent it
- Pin a single Java version across compile and runtime in CI.
- Use
--release N(or the Gradle toolchain) so bytecode targets the intended JDK. - Check that third-party jars support your runtime Java version.