apache/maven · error · IllegalArgumentException

Failed to parse CLI arguments

Error message

Failed to parse CLI arguments: ${message}

What it means

Thrown by the Maven CLI launcher (cling) when Apache Commons CLI reports a ParseException while parsing the raw `mvn` command line (parseArgs with Options.SOURCE_CLI). It means a malformed or unknown option: an option that needs a value got none, an unrecognized flag was passed, or a token starting with `-` could not be matched. The underlying ParseException message is appended and the result rethrown as IllegalArgumentException from MavenParser.parseMavenCliOptions.

Solutions

  1. Fix the exact option named in the appended ParseException text (e.g. `mvn -T 1C clean install` instead of `mvn -T clean install`).
  2. Run `mvn -h` to confirm the option exists in the installed Maven version and note its argument requirements.
  3. Quote -D properties so the shell keeps key=value in one token: `mvn '-DskipTests=true' package`.
  4. Audit @argfiles and .mvn/maven.config referenced by the command, since the same bad option may come from there.
  5. Replace Maven 3 flags removed in Maven 4 with their current equivalents.

Example fix

# before: -T has no value, 'clean' is consumed as its argument
mvn -T clean install

# after: thread count supplied explicitly
mvn -T 1C clean install
Defensive patterns

Strategy: try-catch

Try / catch

try {
    MavenOptions options = parser.parseMavenCliOptions(args);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to parse CLI arguments")) {
        // message carries the Commons CLI reason; report usage, do not retry
        throw new UsageException(e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling `mvn -T` without a thread-count value (the next token is swallowed or missing), passing an unknown flag like `--teer`, giving `-Dmaven.test.skip` without `=value`, or letting a wrapper script/IDE inject a flag removed in the installed Maven version.

Common situations: Typos in -D/-P/-T flags; shell quoting that splits `key=value` into two argv tokens; migrating Maven 3 builds to Maven 4 where old flags were removed; CI scripts reusing stale option names; options accidentally placed after `--`.

Understand the failure class

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/1bd5274c5fab1cbd. Report an issue: GitHub.

Appendix: source

Thrown at impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java:62

            if (Files.isRegularFile(file)) {
                result.add(parseMavenAtFileOptions(file));
            } else {
                throw new IllegalArgumentException("Specified file does not exists (" + file + ")");
            }
        }
        // maven.config; if exists
        Path mavenConfig = context.rootDirectory != null ? context.rootDirectory.resolve(".mvn/maven.config") : null;
        if (mavenConfig != null && Files.isRegularFile(mavenConfig)) {
            result.add(parseMavenConfigOptions(mavenConfig));
        }
        return LayeredMavenOptions.layerMavenOptions(result);
    }

    protected MavenOptions parseMavenCliOptions(List<String> args) {
        try {
            return parseArgs(Options.SOURCE_CLI, args);
        } catch (ParseException e) {
            throw new IllegalArgumentException("Failed to parse CLI arguments: " + e.getMessage(), e.getCause());
        }
    }

    protected MavenOptions parseMavenAtFileOptions(Path atFile) {
        try (Stream<String> lines = Files.lines(atFile, StandardCharsets.UTF_8)) {
            List<String> args =
                    lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toList();
            return parseArgs("atFile", args);
        } catch (ParseException e) {
            throw new IllegalArgumentException(
                    "Failed to parse arguments from file (" + atFile + "): " + e.getMessage(), e.getCause());
        } catch (IOException e) {
            throw new IllegalStateException("Error reading config file: " + atFile, e);
        }
    }

    protected MavenOptions parseMavenConfigOptions(Path configFile) {
        try (Stream<String> lines = Files.lines(configFile, StandardCharsets.UTF_8)) {

View on GitHub (pinned to e4093d4e12)