apache/cassandra · error · IllegalStateException

Must be one of ${values}

Error message

Must be one of ${values}

What it means

Thrown by Stage.fromPoolName when a string does not match any known Cassandra internal stage pool name. The library only maps exact uppercase pool names (e.g. CONCURRENT_MUTATIONS, CONCURRENT_COUNTER_WRITES, CONCURRENT_MATERIALIZED_VIEW_WRITES) to Stage enum constants; anything else is rejected with an IllegalStateException listing all valid values.

Source

Thrown at src/java/org/apache/cassandra/concurrent/Stage.java:120

        try
        {
            return valueOf(upperStageName);
        }
        catch (IllegalArgumentException e)
        {
            switch(upperStageName) // Handle discrepancy between configuration file and stage names
            {
                case "CONCURRENT_READS":
                    return READ;
                case "CONCURRENT_WRITERS":
                    return MUTATION;
                case "CONCURRENT_COUNTER_WRITES":
                    return COUNTER_MUTATION;
                case "CONCURRENT_MATERIALIZED_VIEW_WRITES":
                    return VIEW_MUTATION;
                default:
                    throw new IllegalStateException("Must be one of " + Arrays.stream(values())
                                                                              .map(Enum::toString)
                                                                              .collect(Collectors.joining(",")));
            }
        }
    }

    // Convenience functions to execute on this stage
    public void execute(Runnable task) { executor().execute(task); }
    public void execute(ExecutorLocals locals, Runnable task) { executor().execute(locals, task); }
    public void maybeExecuteImmediately(Runnable task) { executor().maybeExecuteImmediately(task); }
    public <T> Future<T> submit(Callable<T> task) { return executor().submit(task); }
    public Future<?> submit(Runnable task) { return executor().submit(task); }
    public <T> Future<T> submit(Runnable task, T result) { return executor().submit(task, result); }

    public ExecutorPlus executor()
    {
        if (executor == null)
        {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Check the string matches a valid stage pool name exactly (case-sensitive) as listed in the exception message
  2. Print the valid values from Stage.values() before mapping to discover the correct spelling
  3. Handle unknown names explicitly with a default mapping instead of relying on fromPoolName
  4. If the name comes from another node, verify both nodes run the same Cassandra version

Example fix

// before
Stage stage = Stage.fromPoolName(jmxPoolName);
// after
Stage stage = Arrays.stream(Stage.values())
    .filter(s -> s.getJmxName().equalsIgnoreCase(jmxPoolName))
    .findFirst()
    .orElseThrow(() -> new IllegalArgumentException("Unknown pool: " + jmxPoolName));
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidStage(String name) {
    return Arrays.stream(Stage.values())
        .anyMatch(s -> s.name().equals(name));
}

Type guard

Stage asStage(String name) {
    try { return Stage.fromPoolName(name); }
    catch (IllegalStateException e) { return null; }
}

Prevention

When it happens

Trigger: Calling Stage.fromPoolName with a string that is not an exact registered pool name, including wrong case (e.g. 'mutation' instead of 'MUTATION') or names from newer/older Cassandra versions.

Common situations: Parsing thread pool names from JMX or logs to Stages, tools that map executor names after a Cassandra version upgrade renamed or added stages, hand-written MBean automation with a typo.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/4bc9ba1cb623ddd3. Report an issue: GitHub.