apache/cassandra · error · IllegalArgumentException

Extracting tokens from %s sequence is neither necessary nor

Error message

Extracting tokens from %s sequence is neither necessary nor supported here

What it means

GossipHelper.getTokensFromOperation extracts token collections only for bootstrap/replace/move multi-step operations; if invoked with any other operation kind it throws IllegalArgumentException because extracting tokens is meaningless there.

Source

Thrown at src/java/org/apache/cassandra/tcm/compatibility/GossipHelper.java:208

    public static Collection<Token> getTokensFromOperation(NodeId nodeId, ClusterMetadata metadata)
    {
        return getTokensFromOperation(metadata.inProgressSequences.get(nodeId));
    }

    public static Collection<Token> getTokensFromOperation(MultiStepOperation<?> sequence)
    {
        if (null == sequence)
            return Collections.emptySet();

        if (sequence.kind() == MultiStepOperation.Kind.JOIN)
            return new HashSet<>(((BootstrapAndJoin)sequence).finishJoin.tokens);
        else if (sequence.kind() == MultiStepOperation.Kind.REPLACE)
            return new HashSet<>(((BootstrapAndReplace)sequence).bootstrapTokens);
        else if (sequence.kind() == MultiStepOperation.Kind.MOVE)
            return new HashSet<>(((Move)sequence).tokens);

        throw new IllegalArgumentException(String.format("Extracting tokens from %s sequence is neither necessary nor supported here",
                                                         sequence.kind()));
    }

    private static Collection<Token> getTokensIn(IPartitioner partitioner, EndpointState epState)
    {
        try
        {
            if (epState == null)
                return Collections.emptyList();

            VersionedValue versionedValue = epState.getApplicationState(TOKENS);
            if (versionedValue == null)
                return Collections.emptyList();

            return TokenSerializer.deserialize(partitioner, new DataInputStream(new ByteArrayInputStream(versionedValue.toBytes())));
        }
        catch (IOException e)
        {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Only call this helper for BOOTSTRAP/REPLACE/MOVE sequences; handle other kinds at the call site
  2. Extend the method with a branch for the new operation kind if its tokens are genuinely needed
  3. Skip token extraction for the offending sequence during upgrade (it's typically not required)

Example fix

// before
if (sequence.kind() == MultiStepOperation.Kind.LEAVE)
    return getTokensFromOperation(nodeId, metadata); // throws
// after
if (sequence.kind() == MultiStepOperation.Kind.LEAVE)
    return Collections.emptySet(); // tokens not needed for LEAVE
Defensive patterns

Strategy: type-guard

Validate before calling

if (kind != MultiStepOperation.Kind.BOOTSTRAP
 && kind != MultiStepOperation.Kind.REPLACE
 && kind != MultiStepOperation.Kind.MOVE)
    return Collections.emptySet(); // tokens not needed here

Type guard

static boolean hasExtractableTokens(MultiStepOperation<?> seq) {
    MultiStepOperation.Kind k = seq.kind();
    return k == MultiStepOperation.Kind.BOOTSTRAP
        || k == MultiStepOperation.Kind.REPLACE
        || k == MultiStepOperation.Kind.MOVE;
}

Try / catch

try { tokens = getTokensFromOperation(nodeId, metadata); }
catch (IllegalArgumentException e) {
    if (e.getMessage().contains("neither necessary nor supported")) tokens = Collections.emptySet();
    else throw e;
}

Prevention

When it happens

Trigger: Calling getTokensFromOperation with a MultiStepOperation whose kind is not BOOTSTRAP, REPLACE, or MOVE (e.g. a decommission/leave sequence) during the gossip-to-TCM upgrade translation.

Common situations: Upgrade path encountering a node mid-decommission or other operation type; code changes reusing this helper for new sequence kinds without extending it.

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/4587ce2049a6a0fd. Report an issue: GitHub.