SonarSource/sonarqube · error · IllegalStateException
Distributed cluster action in cluster nodes (other nodes…
Error message
Distributed cluster action in cluster nodes (other nodes may have timed out)
What it means
DistributedAnswer.propagateExceptions reports failures of a Hazelcast distributed action across cluster members. When some members returned a failure (failedMembers non-empty), it throws IllegalStateException naming those nodes and attaching the first failure as the cause.
Solutions
- Inspect the attached cause (first failed member's exception) and the named nodes' logs for the root error.
- Restart or repair the failing cluster member(s) listed in the message.
- Verify all nodes run the same SonarQube version and plugins to avoid handling incompatibilities.
Example fix
// operator: check failing node kubectl logs <failed-node-pod> | tail -100 // find the root exception reported as cause // then restart the failing member so it re-joins the cluster
Defensive patterns
Strategy: try-catch
Validate before calling
List<Member> healthy = cluster.getMembers().stream()
.filter(m -> m.getHealth() == MemberHealth.HEALTHY)
.collect(Collectors.toList());
if (healthy.size() < expectedQuorum) {
throw new IllegalStateException("Refusing distributed action: insufficient healthy members");
} Try / catch
try {
distributedAnswer.propagateExceptions();
} catch (IllegalStateException e) {
logger.error("Cluster action failed on nodes: {}; cause: {}", e.getMessage(), e.getCause());
// alert ops / retry after repairing nodes
} Prevention
- Monitor node health and disk/memory on every cluster member.
- Keep all nodes on the same SonarQube and plugin versions.
- Log the failing member's stack trace (the attached cause) for diagnosis.
When it happens
Trigger: Executing a cluster-wide operation (e.g. via HazelcastMemberAddressables/distributed call) where one or more member nodes answered with an exception; propagateExceptions() is then called to surface the error to the caller.
Common situations: A node failing to apply a cluster operation due to local errors (disk full, deserialization failure, internal error) while others succeed; mixed-version cluster where one node cannot handle the action.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Distributed cluster action timed out in cluster nodes
- Address in property is not a valid address
- Embedded database is not supported in cluster mode
- Entries in property must not mix 'host:port' and 'host'…
- Hazelcast must not be enabled on Elasticsearch node
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/1f816ee4277ece86.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-process/src/main/java/org/sonar/process/cluster/hz/DistributedAnswer.java:82
public void setAnswer(Member member, T answer) {
this.answers.put(member, answer);
}
public void setTimedOut(Member member) {
this.timedOutMembers.add(member);
}
public void setFailed(Member member, Exception e) {
failedMembers.put(member, e);
}
public void propagateExceptions() {
if (!failedMembers.isEmpty()) {
String failedMemberNames = failedMembers.keySet().stream()
.map(m -> m.getAttribute(NODE_NAME.getKey()))
.collect(Collectors.joining(", "));
throw new IllegalStateException("Distributed cluster action in cluster nodes " + failedMemberNames + " (other nodes may have timed out)",
failedMembers.values().iterator().next());
}
if (!timedOutMembers.isEmpty()) {
String timedOutMemberNames = timedOutMembers.stream()
.map(m -> m.getAttribute(NODE_NAME.getKey()))
.collect(Collectors.joining(", "));
throw new IllegalStateException("Distributed cluster action timed out in cluster nodes " + timedOutMemberNames);
}
}
/**
* Returns any answer. No guarantees are made on the order. Use this method if you only expect exactly one answer.
* @return the first answer, if any
*/
public Optional<T> getSingleAnswer() {
return answers.values().stream().findFirst();
}View on GitHub (pinned to 184c821202)