SonarSource/sonarqube · error · IllegalStateException

Distributed cluster action timed out in cluster nodes

Error message

Distributed cluster action timed out in cluster nodes 

What it means

DistributedAnswer.propagateExceptions also handles timeouts: when no failures were returned but some members never answered (timedOutMembers non-empty), it throws IllegalStateException listing the timed-out node names.

Solutions

  1. Check the listed nodes' health, CPU, and network connectivity; restart unresponsive nodes.
  2. Increase the distributed-operation timeout if operations are legitimately long-running.
  3. Verify Hazelcast ports (sonar.cluster.hz.port range) are open between all members and no firewall drops packets.

Example fix

// before
sonar.cluster.requestwebservice.timeout=10000
// after
sonar.cluster.requestwebservice.timeout=60000  // or fix the slow node first
Defensive patterns

Strategy: retry

Validate before calling

for (Member m : cluster.getMembers()) {
  if (!m.getAddress().getInetSocketAddress().isResolved() || !ping(m)) {
    throw new IllegalStateException("Member unreachable before distributed action: " + m.getAttribute("name"));
  }
}

Try / catch

try {
  distributedAnswer.propagateExceptions();
} catch (IllegalStateException e) {
  logger.warn("Timed-out nodes: {}", e.getMessage());
  // backoff and retry once after checking node liveness
}

Prevention

When it happens

Trigger: A distributed cluster action whose future timed out on one or more members; propagateExceptions() is called after awaiting answers and finds only timeouts (no explicit failures).

Common situations: Slow or overloaded ES/app node in the SonarQube cluster; network partition delaying Hazelcast responses; timeout configured too low for a heavyweight operation.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/772931e04f256182. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-process/src/main/java/org/sonar/process/cluster/hz/DistributedAnswer.java:90

  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)