quarkusio/quarkus · error · IllegalStateException

Failed to parse MAVEN_OPTS=${mvnOpts}

Error message

Failed to parse MAVEN_OPTS=${mvnOpts}

What it means

getMavenCmdLine() reads the MAVEN_OPTS environment variable and keeps only system-property parts (-D...). Tokenizing MAVEN_OPTS with CommandLineUtils.translateCommandline can fail (unbalanced quotes etc.), producing IllegalStateException 'Failed to parse MAVEN_OPTS=<value>'.

Source

Thrown at independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/options/BootstrapMavenOptions.java:147

        }

        final String mvnLine = System.getenv(MAVEN_CMD_LINE_ARGS);
        if (mvnLine == null) {
            // if the maven command line isn't available we are not checking for MAVEN_OPTS
            return null;
        }

        String mvnOpts = System.getenv("MAVEN_OPTS");
        if (mvnOpts == null) {
            return mvnLine;
        }
        // only retain system properties from MAVEN_OPTS, not something like --add-opens
        try {
            mvnOpts = Arrays.stream(CommandLineUtils.translateCommandline(mvnOpts))
                    .filter(part -> part.startsWith("-" + SYSTEM_PROPERTY))
                    .collect(Collectors.joining(" "));
        } catch (CommandLineException e) {
            throw new IllegalStateException("Failed to parse MAVEN_OPTS=" + mvnOpts, e);
        }
        if (mvnOpts.isEmpty()) {
            return mvnLine;
        }

        final StringBuilder buf = new StringBuilder(mvnLine.length() + mvnOpts.length() + 1);
        buf.append(mvnOpts);
        if (!Character.isWhitespace(mvnLine.charAt(0))) {
            buf.append(' ');
        }
        return buf.append(mvnLine).toString();
    }

    private final Map<String, Object> options;
    private List<String> activeProfileIds;
    private List<String> inactiveProfileIds;

    private BootstrapMavenOptions(Map<String, Object> options) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Print/echo $MAVEN_OPTS and fix the quoting (balanced, properly escaped quotes) or remove problematic entries
  2. Move non -D flags (e.g. --add-opens) with tricky quoting into .mvn/jvm.config instead of MAVEN_OPTS
  3. Run with MAVEN_OPTS unset to confirm this variable is the trigger, then re-add entries one at a time
  4. Only keep simple -Dkey=value system properties in MAVEN_OPTS; this code filters for exactly that anyway

Example fix

// before
export MAVEN_OPTS="-Xmx2g -Dfoo=\"bar\""  # double-escaped
// after
export MAVEN_OPTS="-Xmx2g -Dfoo=bar"
Defensive patterns

Strategy: validation

Validate before calling

String mvnOpts = System.getenv("MAVEN_OPTS");
if (mvnOpts != null) {
    try {
        CommandLineUtils.translateCommandline(mvnOpts);
    } catch (CommandLineException e) {
        throw new IllegalStateException("MAVEN_OPTS cannot be tokenized: " + mvnOpts, e);
    }
}

Try / catch

try {
    BootstrapMavenOptions options = BootstrapMavenOptions.newInstance(cmdLine);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Failed to parse MAVEN_OPTS=")) {
        throw new IllegalStateException("Fix MAVEN_OPTS quoting: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling BootstrapMavenOptions.newInstance() (which calls getMavenCmdLine) when the MAVEN_OPTS environment variable contains quoting that translateCommandline cannot parse - e.g. MAVEN_OPTS="-Xmx1g -Dfoo='bar (unterminated quote)".

Common situations: Hand-edited MAVEN_OPTS in shell profiles with nested quotes, IDE or CI export of MAVEN_OPTS with escaped characters the plexus tokenizer rejects, values copied from docs with smart quotes, or JVM flags like --add-opens="x=y" whose quotes got mangled.

Understand the failure class

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/b3c3610972c782e5. Report an issue: GitHub.