Skip to content
Latchkey

Maven "source release 17 requires target release 17" - Fix in CI

javac rejected a source level newer than the requested bytecode target. You set maven.compiler.source higher than maven.compiler.target, which is not allowed - the target cannot be older than the source.

What this error means

Compilation fails immediately with error: source release 17 requires target release 17. The numbers differ in the message because source was bumped without bumping target (or release was mixed with the older flags).

maven
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile)
on project app: Fatal error compiling: error: source release 17 requires
target release 17 -> [Help 1]

Diagnose it: which JDK is the build actually using?

JVM builds resolve a toolchain from several sources, and the one on PATH is often not the one compiling your code. A version mismatch surfaces as an unsupported class file version rather than as a toolchain error.

Terminal
java -version 2>&1
echo "JAVA_HOME=$JAVA_HOME"
./gradlew -q javaToolchains 2>/dev/null || mvn -v

# class file 65 = Java 21, 61 = Java 17, 55 = Java 11
javap -verbose <SomeClass>.class | grep "major version"

Common causes

source higher than target

A bump of maven.compiler.source to 17 without moving maven.compiler.target leaves target at 11, which javac forbids.

release mixed with source/target

Setting maven.compiler.release and also leaving stale source/target properties produces inconsistent flags.

Inherited property only partly overridden

A parent POM sets both; a child overrides only one, splitting source and target apart.

How to fix it

Use a single release property

Prefer maven.compiler.release so source and target are always consistent and the platform API is enforced.

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

Keep source and target equal

If you must use the older flags, set both to the same level.

pom.xml
<properties>
  <maven.compiler.source>17</maven.compiler.source>
  <maven.compiler.target>17</maven.compiler.target>
</properties>

Remove stale inherited overrides

Delete leftover source/target when switching a module to release.

Terminal
mvn -X compile | grep -i 'compiler.\(source\|target\|release\)'

How to prevent it

  • Standardize on maven.compiler.release across all modules.
  • Avoid mixing release with source/target in the same module.
  • Pin the compiler level in the parent POM and do not partially override it.

Frequently asked questions

What causes Maven "source release 17 requires target release 17"?
There are 3 common causes: source higher than target, release mixed with source/target, and inherited property only partly overridden. A bump of maven.compiler.source to 17 without moving maven.compiler.target leaves target at 11, which javac forbids.
How do I fix Maven "source release 17 requires target release 17"?
There are 3 fixes depending on which cause you have: use a single release property, keep source and target equal, and remove stale inherited overrides. Work through them in order, since the first is the most common.
What does Maven "source release 17 requires target release 17" actually mean?
Compilation fails immediately with error: source release 17 requires target release 17.
How do I stop Maven "source release 17 requires target release 17" happening again?
Standardize on maven.compiler.release across all modules. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card