apache/cassandra · error · RuntimeException

Unhandled return type:

Error message

Unhandled return type: 

What it means

The guardrails-config display code can only render getter return types it knows (strings, numbers, booleans, collections); if a getter returns an unexpected type it throws RuntimeException 'Unhandled return type: <typeName>'. This signals a server/client version mismatch where the MBean exposes a new return type the nodetool formatter does not handle.

Source

Thrown at src/java/org/apache/cassandra/tools/nodetool/GuardrailsConfigCommand.java:161

                Object value = method.invoke(mBean);

                if (returnType.equals(int.class) || returnType.equals(Integer.class)
                    || returnType.equals(long.class) || returnType.equals(Long.class)
                    || returnType.equals(boolean.class) || returnType.equals(Boolean.class)
                    || returnType.equals(Set.class))
                {
                    values.add(value.toString());
                }
                else if (returnType.equals(String.class))
                {
                    if (value == null || value.toString().isEmpty())
                        values.add("null");
                    else
                        values.add(value.toString());
                }
                else
                {
                    throw new RuntimeException("Unhandled return type: " + returnType.getTypeName());
                }
            }

            constructRow(bucket, guardrailName, values.size() == 1 ? values.get(0) : values.toString());
        }
    }

    @Command(name = "setguardrailsconfig", description = "Modify runtime configuration of guardrails.")
    public static class SetGuardrailsConfig extends GuardrailsConfigCommand
    {
        private static final Pattern SETTER_PATTERN = Pattern.compile("^set");

        @CassandraUsage(usage = "[<setter> <value1> ...]",
                description = "For flags, possible values are 'true' or 'false'. " +
                        "For thresholds, two values are expected, first for failure, second for warning. " +
                        "For values, enumeration of values expected or one value where multiple items are separated by comma. " +
                        "Setting for thresholds accepting strings and value guardrails are reset by specifying 'null' or '[]' value. " +
                        "For thresholds accepting integers, the reset value is -1.")

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use a nodetool version matching the server's Cassandra version.
  2. Upgrade to a release where the return type is supported.
  3. Query the guardrail value directly via JMX as a workaround.

Example fix

// before
# nodetool 4.0 against a 5.0 node with a new guardrail type
// after
# run the matching-version nodetool against the node
Defensive patterns

Strategy: try-catch

Try / catch

try {
    display(probe, allGetters, category, expand);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Unhandled return type:")) {
        System.err.println("Client/server version mismatch; use matching nodetool or query JMX directly.");
    } else throw e;
}

Prevention

When it happens

Trigger: Displaying a guardrail whose MBean getter returns a type not covered by addRow's if/else chain (e.g. a newly introduced custom type added to GuardrailsMBean in a newer release while using an older nodetool formatter, or vice versa).

Common situations: Mixed-version clusters where nodetool and the node run different Cassandra versions; newly added guardrails with novel return types.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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