{"record":{"id":"62480d00a72ab68f","repo":"SonarSource/sonarqube","slug":"property-s-must-be-a-local-non-loopback-address","errorCode":null,"errorMessage":"Property %s must be a local non-loopback address: %s","messagePattern":"Property (.+?) must be a local non-loopback address: (.+?)","errorType":"validation","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java","lineNumber":216,"sourceCode":"    if (trimmedJdbcUrl == null || trimmedJdbcUrl.isEmpty() || trimmedJdbcUrl.startsWith(\"jdbc:h2:\")) {\n      throw new MessageException(\"Embedded database is not supported in cluster mode\");\n    }\n  }\n\n  private void ensureNotLoopbackAddresses(Property property, Set<AddressAndPort> hostAndPorts) {\n    Set<AddressAndPort> loopbackAddresses = hostAndPorts.stream()\n      .filter(t -> network.isLoopback(t.getHost()))\n      .collect(toSet());\n    if (!loopbackAddresses.isEmpty()) {\n      throw new MessageException(format(\"Property %s must not contain a loopback address: %s\", property.getKey(),\n        loopbackAddresses.stream().map(AddressAndPort::getHost).sorted().collect(Collectors.joining(\", \"))));\n    }\n  }\n\n  private void ensureLocalButNotLoopbackAddress(Property property, AddressAndPort addressAndPort) {\n    String host = addressAndPort.getHost();\n    if (!network.isLocal(host) || network.isLoopback(host)) {\n      throw new MessageException(format(\"Property %s must be a local non-loopback address: %s\", property.getKey(), addressAndPort.getHost()));\n    }\n  }\n\n  private static void ensureEitherPortsAreProvidedOrOnlyHosts(Property property, Set<AddressAndPort> addressAndPorts) {\n    Set<AddressAndPort> hostsWithoutPort = addressAndPorts.stream()\n      .filter(t -> !t.hasPort())\n      .collect(toSet());\n    if (!hostsWithoutPort.isEmpty() && hostsWithoutPort.size() != addressAndPorts.size()) {\n      throw new MessageException(format(\"Entries in property %s must not mix 'host:port' and 'host'. Provide hosts without port only or hosts with port only.\", property.getKey()));\n    }\n  }\n\n  private static class AddressAndPort {\n    private static final int NO_PORT = -1;\n\n    /**\n     * the host from setting, can be a hostname or an IP address\n     */","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java#L198-L234","documentation":"Some cluster properties must point at an address bound to the local machine but not to loopback. ensureLocalButNotLoopbackAddress checks the single AddressAndPort via network.isLocal and network.isLoopback and throws MessageException when the host is either not local to this machine or is a loopback address.","triggerScenarios":"Called from checkForSearchNode and checkClusterNodeHost for properties such as sonar.cluster.node.host and the search node's host: it throws when network.isLocal(host) is false (host not bound to this machine) or network.isLoopback(host) is true (localhost/127.0.0.1).","commonSituations":"Pointing sonar.cluster.node.host at another node's IP by copy-paste; using 'localhost' on a search node; running in a container where the configured IP belongs to the host machine but not the container network namespace.","solutions":["Set the property to an IP/DNS name actually assigned to this machine's network interface (e.g. the pod IP in Kubernetes, or output of 'ip addr').","Avoid localhost/127.0.0.1 even though it is 'local' — loopback is explicitly rejected.","In containers, ensure the address is valid inside the container's namespace, not the host's."],"exampleFix":"// before (conf/sonar.properties)\nsonar.cluster.node.host=192.168.1.99  # another node's IP\n\n// after\nsonar.cluster.node.host=192.168.1.10  # this node's own IP","handlingStrategy":"validation","validationCode":"// shell: the node host must be one of this machine's own non-loopback addresses\nhost=$(grep -E '^sonar\\.cluster\\.node\\.host=' conf/sonar.properties | cut -d= -f2)\nip -o addr show | grep -qw \"$host\" || echo \"sonar.cluster.node.host=$host is not a local interface address\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive sonar.cluster.node.host from the actual interface IP (e.g. via cloud-init/envsubst) per node","Never copy-paste node configs between machines without changing the host value","In containers, use the container/pod IP, not the host's"],"tags":["network","cluster","configuration","bind-address"],"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"}