apache/maven · error · ExitException
Directory {} extracted from the -f/--file command-line argum
Error message
Directory {} extracted from the -f/--file command-line argument {} does not exist What it means
While pre-scanning raw arguments for -f/--file, MavenCli resolves the value against the current top directory. If the value is an existing regular file (a POM), its parent directory becomes the new top directory; when that parent then fails Files.isDirectory (concurrently removed, a dangling symlink used as the file's parent, or a permission-denied stat), 'Directory <parent> extracted from the -f/--file command-line argument <arg> does not exist' is printed and ExitException stops startup with code 1.
Source
Thrown at compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:371
}
// 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));
if (Files.isDirectory(path)) {
topDirectory = path;
} else if (Files.isRegularFile(path)) {
topDirectory = path.getParent();
if (!Files.isDirectory(topDirectory)) {
System.err.println("Directory " + topDirectory
+ " extracted from the -f/--file command-line argument " + arg + " does not exist");
throw new ExitException(1);
}
} else {
System.err.println(
"POM file " + arg + " specified with the -f/--file command line argument does not exist");
throw new ExitException(1);
}
break;
} else {
// Check if this is the -f/--file option
isAltFile = arg.equals("-f") || arg.equals("--file");
}
}
topDirectory = getCanonicalPath(topDirectory);
cliRequest.topDirectory = topDirectory;
// We're very early in the process, and we don't have the container set up yet,
// so we rely on the JDK services to eventually look up a custom RootLocator.
// This is used to compute {@code session.rootDirectory} but all {@code project.rootDirectory}
// properties will be computed through the RootLocator found in the container.View on GitHub (pinned to e4093d4e12)
Solutions
- Re-run with the parent directory itself: mvn -f /real/parent/dir (Maven will find pom.xml there)
- Replace symlinked intermediate directories in the -f path with the real path (readlink -f to canonicalize)
- Verify with ls -la that every path segment of the -f argument is a real directory
- If a script deletes/recreates the module directory, ensure it completes before mvn starts
Example fix
# before: 'build' is a dangling symlink mvn -f ./build/pom.xml # after: use the real directory mvn -f /workspace/modules/app
Defensive patterns
Strategy: validation
Validate before calling
import java.nio.file.*;
// pre-check a -f argument before invoking Maven
Path arg = Paths.get(fValue).toRealPath(); // throws if any symlink is broken
Path topDir = Files.isDirectory(arg) ? arg : arg.getParent();
if (!Files.isDirectory(topDir)) {
throw new IllegalArgumentException("-f argument parent is not a usable directory: " + topDir);
} Try / catch
catch (ExitException e) {
if (stderrCapture.contains("extracted from the -f/--file command-line argument")) {
// pass the parent directory itself instead of the pom path and retry once
retryWithArguments(replaceArgument(args, fValue, topDirectoryAsString));
}
} Prevention
- Canonicalize -f paths in wrapper scripts with readlink -f / realpath before invoking mvn
- Avoid symlinks in module paths on shared build machines; use real checkout paths
- Have scripts verify each path segment exists before launching the build
When it happens
Trigger: mvn -f <pom> where <pom> resolves to a regular file but its parent directory is not a usable directory at check time — parent symlink chain broken, directory deleted between the two checks, or unusual filesystems (some network/FUSE mounts) where isDirectory on the parent fails.
Common situations: Pointing -f at a path through a symlinked directory whose target was moved; build scripts racing with directory cleanup; container mounts where the parent directory is present in the image but masked at runtime.
Related errors
- Non-existing JDK home configuration at " + normal.toAbsolute
- POM file {} specified with the -f/--file command line argume
- Non-existing JDK home configuration at
- Unbounded range: {}
- Ranges overlap: {}
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/471fdb3a65af504f.
Report an issue: GitHub.