SonarSource/sonarqube · error · MessageException
a JVM option can't overwrite mandatory JVM options. %s overw
Error message
a JVM option can't overwrite mandatory JVM options. %s overwrites %s
What it means
The single-value variant of checkMandatoryOptionOverwrite validates one user-supplied JVM option and throws a MessageException if it would overwrite a mandatory option SonarQube force-sets on the child JVM. The message names both the offending value and the mandatory option (key+value) it would replace.
Source
Thrown at server/sonar-main/src/main/java/org/sonar/application/command/JvmOptions.java:129
*
* @throws IllegalArgumentException if argument is empty or does not start with {@code -}.
*/
public T add(String str) {
requireNonNull(str, JVM_OPTION_NOT_NULL_ERROR_MESSAGE);
String value = str.trim();
if (isInvalidOption(value)) {
throw new IllegalArgumentException("a JVM option can't be empty and must start with '-'");
}
checkMandatoryOptionOverwrite(value);
options.add(value);
return castThis();
}
private void checkMandatoryOptionOverwrite(String value) {
Map.Entry<String, String> overriddenMandatoryOption = mandatoryOptionFor(value);
if (overriddenMandatoryOption != null) {
throw new MessageException(String.format(
"a JVM option can't overwrite mandatory JVM options. %s overwrites %s",
value,
overriddenMandatoryOption.getKey() + overriddenMandatoryOption.getValue()));
}
}
@CheckForNull
private Map.Entry<String, String> mandatoryOptionFor(String jvmOption) {
return mandatoryOptions.entrySet().stream()
.filter(s -> jvmOption.startsWith(s.getKey()) && !jvmOption.equals(s.getKey() + s.getValue()))
.findFirst()
.orElse(null);
}
private static boolean isInvalidOption(String value) {
return value.isEmpty() || !value.startsWith("-");
}
View on GitHub (pinned to 184c821202)
Solutions
- Delete the colliding option from the user JVM options property
- Let SonarQube control that setting through its dedicated property (e.g. heap-size properties for Elasticsearch)
- Read 'X overwrites Y' in the message to see the reserved option (Y) and remove user option (X)
- Re-check the property after SonarQube upgrades, as the set of mandatory options can grow
Example fix
// before sonar.web.javaOpts=-Xmx1024m -Xms512m // after (non-reserved flags only) sonar.web.javaOpts=-XX:+HeapDumpOnOutOfMemoryError
Defensive patterns
Strategy: validation
Validate before calling
boolean conflictsWithMandatory(String opt, Map<String,String> mandatory) {
return mandatory.keySet().stream().anyMatch(k -> opt.startsWith(k));
} Try / catch
try {
launcher.start();
} catch (MessageException e) {
if (e.getMessage().contains("overwrites")) {
log.error("User JVM option conflicts with a mandatory option", e);
}
} Prevention
- Consult the mandatory option list for each process type before customizing javaOpts
- Keep user JVM options limited to non-reserved tuning flags
- Test javaOpts changes on a staging node first
When it happens
Trigger: Calling addFromMandatoryProperty with a single JVM option string whose key matches a reserved mandatory option, e.g. passing -Xmx or -Xms where the process heap is managed by SonarQube itself.
Common situations: Hand-tuning child process heap or GC flags that newer SonarQube versions reserve, applying the same javaOpts template to all processes when one process has that option reserved.
Related errors
- a JVM option can't overwrite mandatory JVM options. The foll
- a JVM option can't be empty and must start with '-'. The fol
- %s is not a valid url
- Error while executing a call to %s. Return code %s. Error me
- SonarQube was not able to retrieve resources from external s
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/d77dc675875aae6b.
Report an issue: GitHub.