{"record":{"id":"10d8ed84192af787","repo":"SonarSource/sonarqube","slug":"a-jvm-option-can-t-be-empty-and-must-start-with","errorCode":null,"errorMessage":"a JVM option can't be empty and must start with '-'. The following JVM options defined by property '%s' are invalid: %s","messagePattern":"a JVM option can't be empty and must start with '-'\\. The following JVM options defined by property '(.+?)' are invalid: (.+?)","errorType":"validation","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"server/sonar-main/src/main/java/org/sonar/application/command/JvmOptions.java","lineNumber":85,"sourceCode":"  public T addFromMandatoryProperty(Props props, String propertyName) {\n    String value = props.nonNullValue(propertyName);\n    if (!value.isEmpty()) {\n      String splitRegex = \" (?=-)\";\n      List<String> jvmOptions = Arrays.stream(value.split(splitRegex)).map(String::trim).toList();\n      checkOptionFormat(propertyName, jvmOptions);\n      checkMandatoryOptionOverwrite(propertyName, jvmOptions);\n      options.addAll(jvmOptions);\n    }\n\n    return castThis();\n  }\n\n  private static void checkOptionFormat(String propertyName, List<String> jvmOptionsFromProperty) {\n    List<String> invalidOptions = jvmOptionsFromProperty.stream()\n      .filter(JvmOptions::isInvalidOption)\n      .toList();\n    if (!invalidOptions.isEmpty()) {\n      throw new MessageException(format(\n        \"a JVM option can't be empty and must start with '-'. The following JVM options defined by property '%s' are invalid: %s\",\n        propertyName,\n        invalidOptions.stream()\n          .collect(joining(\", \"))));\n    }\n  }\n\n  private void checkMandatoryOptionOverwrite(String propertyName, List<String> jvmOptionsFromProperty) {\n    List<Match> matches = jvmOptionsFromProperty.stream()\n      .map(jvmOption -> new Match(jvmOption, mandatoryOptionFor(jvmOption)))\n      .filter(match -> match.mandatoryOption() != null)\n      .toList();\n    if (!matches.isEmpty()) {\n      throw new MessageException(format(\n        \"a JVM option can't overwrite mandatory JVM options. The following JVM options defined by property '%s' are invalid: %s\",\n        propertyName,\n        matches.stream()\n          .map(m -> m.option() + \" overwrites \" + m.mandatoryOption.getKey() + m.mandatoryOption.getValue())","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-main/src/main/java/org/sonar/application/command/JvmOptions.java#L67-L103","documentation":"JvmOptions.checkOptionFormat validates JVM options sourced from a SonarQube property before they are applied to a child process. Each option must be non-empty and start with '-'; any entry failing this check causes a MessageException listing the offending values, preventing misconfigured JVM flags from breaking process startup.","triggerScenarios":"Setting a JVM options property (e.g. sonar.web.javaOpts, sonar.ce.javaOpts, sonar.search.javaOpts) with empty entries, values missing the leading dash (like 'Xmx2G' instead of '-Xmx2G'), or stray spaces/commas producing empty tokens.","commonSituations":"Copy-pasting JVM flags from documentation without the leading '-', trailing commas or double spaces in the property value, or leaving an empty value that still yields an empty list element after splitting.","solutions":["Prefix every option in the property with '-'; e.g. change Xmx2G to -Xmx2G","Remove empty entries, stray commas and extra whitespace from the property value","Validate the property value with the code below before startup","Restart and confirm the child process JVM receives the corrected options"],"exampleFix":"// before\nsonar.web.javaOpts=Xmx2G -XX:MaxMetaspaceSize=512M\n// after\nsonar.web.javaOpts=-Xmx2G -XX:MaxMetaspaceSize=512M","handlingStrategy":"validation","validationCode":"List<String> opts = List.of(javaOptsProperty.split(\"\\\\s+\"));\nList<String> bad = opts.stream()\n  .filter(o -> o.isEmpty() || !o.startsWith(\"-\"))\n  .toList();\nif (!bad.isEmpty()) throw new IllegalArgumentException(\"invalid JVM options: \" + bad);","typeGuard":null,"tryCatchPattern":"try {\n  launcher.start();\n} catch (MessageException e) {\n  if (e.getMessage().contains(\"must start with '-'\")) {\n    log.error(\"Fix javaOpts property formatting\", e);\n  }\n}","preventionTips":["Always prefix JVM flags with '-' in javaOpts properties","Avoid stray commas/double spaces in property values","Lint sonar.properties values before deploying"],"tags":["java","jvm","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}