Skip to content
Latchkey

Maven "Fatal error compiling: invalid target release" - Fix JDK

The maven-compiler-plugin was told to target a Java version newer than the JDK actually running the build. A JDK 17 cannot emit --release 21 bytecode - it does not know that version.

What this error means

Compilation aborts with Fatal error compiling: invalid target release: 21 (or similar). The number is the version your POM requests; the running JDK is older than it.

mvn output
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile)
on project app: Fatal error compiling: invalid target release: 21

Common causes

JAVA_HOME points at an older JDK

The runner’s JDK is older than the <release>/<target> in the compiler config. CI defaulted to JDK 17 while the project targets 21.

maven.compiler.release set higher than the toolchain

A <maven.compiler.release>21</maven.compiler.release> (or --release 21) demands a JDK that understands version 21. An older JDK rejects it outright.

How to fix it

Set up the matching JDK in CI

Provision the JDK version your project targets so the compiler can emit that bytecode.

.github/workflows/ci.yml
- uses: actions/setup-java@v4
  with:
    distribution: temurin
    java-version: '21'
- run: mvn -B -version   # confirm Maven uses JDK 21

Align the release with the available JDK

If you cannot upgrade the JDK, lower the target. The release must be <= the running JDK.

pom.xml
<properties>
  <maven.compiler.release>17</maven.compiler.release>
</properties>

How to prevent it

  • Pin the JDK version in CI with setup-java and assert it with mvn -version.
  • Keep maven.compiler.release and the provisioned JDK in lockstep.
  • Use Maven Toolchains to bind a specific JDK independent of JAVA_HOME.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →