SonarSource/sonarqube · error · IllegalArgumentException

Unexpected node type

Error message

Unexpected node type 

What it means

ClusterSettings.getEnabledProcesses maps a NodeType to the processes that node should run. The switch handles APPLICATION and SEARCH and throws an IllegalArgumentException 'Unexpected node type ' for anything else. Given toNodeType validates input against NodeType beforehand, reaching the default branch indicates an internal invariant violation (an unknown enum constant), not operator error.

Solutions

  1. If you patched SonarQube and added a NodeType constant, extend the switch in getEnabledProcesses to return the correct process list for it.
  2. Otherwise this is a bug: report it with the full stack trace and the exact sonar-cluster node type value logged.
  3. As a workaround, revert to a supported node type ('application' or 'search') in sonar.cluster.node.type.

Example fix

// before
switch (nodeType) {
  case APPLICATION: return asList(ProcessId.WEB_SERVER, ProcessId.COMPUTE_ENGINE);
  case SEARCH: return singletonList(ProcessId.ELASTICSEARCH);
  default: throw new IllegalArgumentException("Unexpected node type " + nodeType);
}

// after (when adding a new node type)
switch (nodeType) {
  case APPLICATION: return asList(ProcessId.WEB_SERVER, ProcessId.COMPUTE_ENGINE);
  case SEARCH: return singletonList(ProcessId.ELASTICSEARCH);
  case NEW_ROLE: return asList(ProcessId.WEB_SERVER);
  default: throw new IllegalArgumentException("Unexpected node type " + nodeType);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  List<ProcessId> processes = ClusterSettings.getEnabledProcesses(settings);
} catch (IllegalArgumentException e) {
  // internal invariant broken: unknown NodeType reached the switch
  log.error("Unknown node type; verify no custom NodeType enum values were added without updating getEnabledProcesses", e);
  throw e;
}

Prevention

When it happens

Trigger: getEnabledProcesses throws only if nodeType is a NodeType value not covered by the switch — practically impossible via normal configuration since toNodeType already restricted values to APPLICATION/SEARCH; it can only occur with a new NodeType enum value added without updating this switch, or via direct programmatic invocation.

Common situations: Custom patches or forks adding a NodeType constant (e.g. a new node role) without extending getEnabledProcesses; version skew where a plugin/patch introduces an enum value the running switch does not know.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java:278

  /**
   * Hazelcast must be started when cluster is activated on all nodes but search ones
   */
  public static boolean shouldStartHazelcast(AppSettings appSettings) {
    return isClusterEnabled(appSettings.getProps()) && toNodeType(appSettings.getProps()).equals(NodeType.APPLICATION);
  }

  public static List<ProcessId> getEnabledProcesses(AppSettings settings) {
    if (!isClusterEnabled(settings)) {
      return asList(ProcessId.ELASTICSEARCH, ProcessId.WEB_SERVER, ProcessId.COMPUTE_ENGINE);
    }
    NodeType nodeType = NodeType.parse(settings.getValue(CLUSTER_NODE_TYPE.getKey()).orElse(""));
    switch (nodeType) {
      case APPLICATION:
        return asList(ProcessId.WEB_SERVER, ProcessId.COMPUTE_ENGINE);
      case SEARCH:
        return singletonList(ProcessId.ELASTICSEARCH);
      default:
        throw new IllegalArgumentException("Unexpected node type " + nodeType);
    }
  }

  public static boolean isLocalElasticsearchEnabled(AppSettings settings) {
    // elasticsearch is enabled on "search" nodes, but disabled on "application" nodes
    if (isClusterEnabled(settings.getProps())) {
      return NodeType.parse(settings.getValue(CLUSTER_NODE_TYPE.getKey()).orElse("")) == NodeType.SEARCH;
    }

    // elasticsearch is enabled in standalone mode
    return true;
  }
}

View on GitHub (pinned to 184c821202)