{"record":{"id":"740db7af8474a09d","repo":"SonarSource/sonarqube","slug":"property-s-is-mandatory","errorCode":null,"errorMessage":"Property %s is mandatory","messagePattern":"Property (.+?) is mandatory","errorType":"validation","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java","lineNumber":179,"sourceCode":"    checkValidHosts(property, singleton(addressAndPort));\n    return addressAndPort;\n  }\n\n  public static NodeType toNodeType(Props props) {\n    String nodeTypeValue = requireValue(props, CLUSTER_NODE_TYPE);\n    if (!NodeType.isValid(nodeTypeValue)) {\n      throw new MessageException(format(\"Invalid value for property %s: [%s], only [%s] are allowed\", CLUSTER_NODE_TYPE.getKey(), nodeTypeValue,\n        Arrays.stream(NodeType.values()).map(NodeType::getValue).collect(joining(\", \"))));\n    }\n    return NodeType.parse(nodeTypeValue);\n  }\n\n  private static String requireValue(Props props, Property property) {\n    String key = property.getKey();\n    String value = props.value(key);\n    String trimmedValue = value == null ? null : value.trim();\n    if (trimmedValue == null || trimmedValue.isEmpty()) {\n      throw new MessageException(format(\"Property %s is mandatory\", key));\n    }\n    return trimmedValue;\n  }\n\n  private static void ensureNoSearchNodeForbiddenSettings(Props props) {\n    List<String> violations = FORBIDDEN_SEARCH_NODE_SETTINGS.stream()\n      .filter(setting -> props.value(setting.getKey()) != null)\n      .map(Property::getKey)\n      .toList();\n\n    if (!violations.isEmpty()) {\n      throw new MessageException(format(\"Properties [%s] are not allowed when running SonarQube in cluster mode.\", String.join(\", \", violations)));\n    }\n  }\n\n  private static void ensureNotH2(Props props) {\n    String jdbcUrl = props.value(JDBC_URL.getKey());\n    String trimmedJdbcUrl = jdbcUrl == null ? null : jdbcUrl.trim();","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java#L161-L197","documentation":"ClusterSettings.requireValue enforces that a required cluster property has a non-null, non-blank value. It trims the raw value and throws MessageException 'Property %s is mandatory' when the value is missing entirely or contains only whitespace, returning the trimmed value otherwise.","triggerScenarios":"Called by checkForApplicationNode, hzNodes, searchHost, esHost, clusterNodeHost, and searchHosts whenever a required property such as sonar.cluster.node.type, sonar.cluster.node.host, sonar.cluster.search.hosts, or sonar.cluster.es.hosts is absent or empty during accept() validation.","commonSituations":"Cluster mode enabled (sonar.cluster.enabled=true) but per-node properties never added; property left as empty placeholder 'sonar.cluster.node.host='; value containing only spaces after an edit; environment-variable substitution that resolved to nothing.","solutions":["Set the property named in the message to a concrete value in conf/sonar.properties (e.g. sonar.cluster.node.host=<this node's IP>).","Remove trailing/leading whitespace-only values and re-enter the value; an empty or blank value is treated as missing.","If this node should not be clustered, disable clustering instead (sonar.cluster.enabled=false) so the check is skipped."],"exampleFix":"// before (conf/sonar.properties)\nsonar.cluster.enabled=true\nsonar.cluster.node.host=\n\n// after\nsonar.cluster.enabled=true\nsonar.cluster.node.host=192.168.1.10","handlingStrategy":"validation","validationCode":"// shell: fail fast if a required cluster property is blank\nfor key in sonar.cluster.node.type sonar.cluster.node.host sonar.cluster.search.hosts; do\n  v=$(grep -E \"^${key}=\" conf/sonar.properties | cut -d= -f2 | tr -d ' ')\n  [ -z \"$v\" ] && echo \"Property $key is mandatory\" && exit 1\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When enabling sonar.cluster.enabled=true, immediately add all per-node required properties","Never leave placeholder empty values in sonar.properties","Verify env-var substitutions expand to non-empty values at startup"],"tags":["configuration","cluster","missing-property","sonarqube"],"backgroundTag":"missing-required-config-field","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"}