apache/maven · error · ToolchainFactoryException
Non-existing JDK home configuration at
Error message
Non-existing JDK home configuration at
What it means
DefaultJavaToolchainFactory validates that the path given in <jdkHome> exists on the filesystem before accepting the toolchain. Paths.get(value).normalize() is checked with Files.exists; a path that does not resolve to an existing directory throws ToolchainFactoryException with the absolute path in the message. Note that existence is checked from the machine running Maven, not the machine that wrote the file.
Source
Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java:86
String key = entry.getKey();
String value = entry.getValue();
if (value == null) {
throw new ToolchainFactoryException(
"Provides token '" + key + "' doesn't have any value configured.");
}
return "version".equals(key) ? new VersionMatcher(versionParser, value) : new ExactMatcher(value);
}));
// compute and normalize the java home
XmlNode dom = model.getConfiguration();
XmlNode javahome = dom != null ? dom.child(KEY_JAVAHOME) : null;
if (javahome == null || javahome.value() == null) {
throw new ToolchainFactoryException(
"Java toolchain without the " + KEY_JAVAHOME + " configuration element.");
}
Path normal = Paths.get(javahome.value()).normalize();
if (!Files.exists(normal)) {
throw new ToolchainFactoryException("Non-existing JDK home configuration at " + normal.toAbsolutePath());
}
String javaHome = normal.toString();
Version javaVersion = model.getProvides().entrySet().stream()
.filter(entry -> "version".equals(entry.getKey()))
.map(Map.Entry::getValue)
.map(versionParser::parseVersion)
.findAny()
.orElse(null);
return new DefaultJavaToolchain(model, javaHome, javaVersion, matchers);
}
@Nonnull
@Override
public Optional<Toolchain> createDefaultToolchain() {
return Optional.empty();
}View on GitHub (pinned to e4093d4e12)
Solutions
- Correct jdkHome to an existing JDK directory on this machine (verify with ls /path)
- Use environment-relative setup: JAVA_HOME-based toolchain discovery or keep per-machine toolchains.xml in ~/.m2 instead of committing it
- On CI, install the expected JDK at the documented path or generate toolchains.xml in the pipeline
Example fix
<!-- before --> <jdkHome>/usr/lib/jvm/java-17-openjdk</jdkHome> <!-- removed by upgrade --> <!-- after --> <jdkHome>/usr/lib/jvm/java-21-openjdk</jdkHome>
Defensive patterns
Strategy: validation
Validate before calling
String home = jdkHome.value();
if (!Files.isDirectory(Paths.get(home))) {
throw new IllegalArgumentException('jdkHome does not exist on this machine: ' + home);
} Prevention
- Keep toolchains.xml per-machine (~/.m2) instead of committing absolute paths
- In CI, install JDKs at fixed paths and generate toolchains.xml in the pipeline
- Re-check paths after JDK upgrades or OS updates
When it happens
Trigger: toolchains.xml pointing to a JDK location that is absent on the current machine: /usr/lib/jvm/java-17 on a host where the JDK was upgraded/removed, or a developer-specific path (C:\Users\alice\...) used by another developer or CI runner.
Common situations: Team-committed or copied toolchains.xml with machine-specific paths; macOS JDK version bump invalidating /Library/Java/JavaVirtualMachines/...; container images where the JDK lives at a different prefix; symlinks removed after OS updates; typo in the path.
Related errors
- Non-existing JDK home configuration at " + normal.toAbsolute
- Java toolchain without the jdkHome configuration element.
- Directory {} extracted from the -f/--file command-line argum
- Provides token '" + key + "' doesn't have any value configur
- Java toolchain without the jdkHome configuration element.
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/e06261c41a5c274a.
Report an issue: GitHub.