{"record":{"id":"c0c9042c4759c4f6","repo":"SonarSource/sonarqube","slug":"property-s-must-not-contain-a-loopback-address","errorCode":null,"errorMessage":"Property %s must not contain a loopback address: %s","messagePattern":"Property (.+?) must not contain a loopback address: (.+?)","errorType":"validation","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java","lineNumber":208,"sourceCode":"    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();\n    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    }","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java#L190-L226","documentation":"Cluster nodes must advertise routable addresses. ensureNotLoopbackAddresses filters the parsed host set of a cluster property through network.isLoopback and throws a MessageException naming the property and every loopback host found, because localhost/127.0.0.1/::1 addresses cannot be reached by other cluster members.","triggerScenarios":"Called from checkForApplicationNode, checkClusterSearchHosts, and checkClusterEsHosts when properties like sonar.cluster.node.host, sonar.cluster.search.hosts, or sonar.cluster.es.hosts contain a host that resolves to a loopback address.","commonSituations":"Setting sonar.cluster.node.host=localhost or 127.0.0.1 in sonar.properties; using hostname 'localhost' in container configs where the operator assumed the service DNS name; template defaults never overridden per node.","solutions":["Replace the loopback host with the node's real, routable IP or DNS name in the property named in the message.","For multi-node clusters ensure each node advertises an address reachable by peers (e.g. the pod/service IP in Kubernetes).","If the host is a name, verify it resolves to a non-loopback address on the network (check /etc/hosts for entries mapping the name to 127.0.0.1)."],"exampleFix":"// before (conf/sonar.properties)\nsonar.cluster.node.host=127.0.0.1\n\n// after\nsonar.cluster.node.host=192.168.1.10","handlingStrategy":"validation","validationCode":"// shell: reject loopback hosts in cluster properties\nfor h in $(grep -E '^sonar\\.cluster\\.' conf/sonar.properties | cut -d= -f2 | tr ',' ' '); do\n  case \"$h\" in localhost|127.*|::1|0:0:0:0:0:0:0:1) echo \"Loopback host not allowed: $h\"; exit 1;; esac\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use localhost/127.0.0.1 for any sonar.cluster.* host property","Check /etc/hosts for names silently mapped to 127.0.0.1","Use each node's routable IP or cluster-internal DNS name"],"tags":["network","cluster","loopback","configuration"],"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"}