apache/maven · error · ExitException
-D%s system property is not set.
Error message
-D%s system property is not set.
What it means
MavenCli.initialize() requires the system property maven.multiModuleProjectDirectory to be set: it locates the root of the multi-module project (the directory containing .mvn). The official mvn/mvnw launcher scripts export it before starting the JVM; if the JVM is started without it (for example by invoking org.apache.maven.cli.MavenCli.main directly or through a custom launcher), the message '-Dmaven.multiModuleProjectDirectory system property is not set.' is printed to stderr and ExitException aborts startup with code 1.
Source
Thrown at compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:345
return 1;
} finally {
if (localContainer != null) {
localContainer.dispose();
}
}
}
void initialize(CliRequest cliRequest) throws ExitException {
if (cliRequest.workingDirectory == null) {
cliRequest.workingDirectory = System.getProperty("user.dir");
}
if (cliRequest.multiModuleProjectDirectory == null) {
String basedirProperty = System.getProperty(MULTIMODULE_PROJECT_DIRECTORY);
if (basedirProperty == null) {
System.err.format("-D%s system property is not set.", MULTIMODULE_PROJECT_DIRECTORY);
throw new ExitException(1);
}
File basedir = new File(basedirProperty);
try {
cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
} catch (IOException e) {
cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
}
}
// We need to locate the top level project which may be pointed at using
// the -f/--file option. However, the command line isn't parsed yet, so
// we need to iterate through the args to find it and act upon it.
Path topDirectory = fileSystem.getPath(cliRequest.workingDirectory);
boolean isAltFile = false;
for (String arg : cliRequest.args) {
if (isAltFile) {
// this is the argument following -f/--file
Path path = topDirectory.resolve(stripLeadingAndTrailingQuotes(arg));View on GitHub (pinned to e4093d4e12)
Solutions
- Invoke Maven through the standard mvn or mvnw scripts, which set the property automatically
- If you must start the JVM yourself, add -Dmaven.multiModuleProjectDirectory=$PWD (pointing at the project root containing .mvn, or the cwd)
- In IDE run configurations, launch via the IDE's Maven integration or MavenExec/IdeMain-style helpers rather than a bare main() call
- Ensure the launcher you use ships from the same Maven version as the embedded classes (mixing an old script with new embedder classes causes this)
Example fix
# before
java -classpath maven-embedder.jar:... org.apache.maven.cli.MavenCli compile
# -> -Dmaven.multiModuleProjectDirectory system property is not set.
# after
java -Dmaven.multiModuleProjectDirectory="$PWD" \
-classpath maven-embedder.jar:... org.apache.maven.cli.MavenCli compile Defensive patterns
Strategy: validation
Validate before calling
import org.apache.maven.cli.MavenCli;
// before embedding/invoking MavenCli main
String basedir = System.getProperty(MavenCli.MULTIMODULE_PROJECT_DIRECTORY);
if (basedir == null) {
System.setProperty(MavenCli.MULTIMODULE_PROJECT_DIRECTORY, System.getProperty("user.dir"));
}
// now safe to invoke MavenCli.main(args) Try / catch
try {
cli.doMain(args, workingDir, stdout, stderr);
} catch (ExitException e) {
if (stderrCapture.contains("multiModuleProjectDirectory")) {
retryWithSystemProperty("-Dmaven.multiModuleProjectDirectory=" + workingDir); // fix and rerun once
} else {
process.exit(e.getExitCode());
}
} Prevention
- Always launch Maven through mvn / mvnw scripts or the IDE's Maven runner — they set the property for you
- In embedded tooling, set the system property programmatically before calling MavenCli, sourced from the detected project root
- Pin launcher scripts and embedder to the same Maven version to avoid property-contract mismatches
When it happens
Trigger: Running java -classpath ... org.apache.maven.cli.MavenCli (or MavenCli.doMain in embedded tooling) without -Dmaven.multiModuleProjectDirectory=<dir>; using a third-party launcher or IDE run configuration that starts the Maven JVM itself and does not set the property.
Common situations: Developers starting MavenCli from an IDE 'main class' run configuration instead of the mvn script; custom Gradle/CI wrappers invoking the embedded Maven CLI; older or stripped-down launch scripts from Maven distributions predating 3.3.1 (when the property was introduced).
Related errors
- Ranges overlap: {}
- Range defies version ordering: {}
- Unbounded range: {}
- The property name is required to activate the profile '{}'
- Directory {} extracted from the -f/--file command-line argum
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/d92a2a706721c121.
Report an issue: GitHub.