apache/cassandra · error · IllegalStateException

Could not find range for token in ReplicaGroups:

Error message

Could not find range for token  in ReplicaGroups: 

What it means

ReplicaGroups.forRange looks up the placement group owning a given token via a CEIL binary search over the sorted ranges. It throws IllegalStateException when the binary search fails to land on an existing range entry, i.e. the token lies outside every range this ReplicaGroups object covers, or its internal index is inconsistent.

Solutions

  1. Refresh ClusterMetadata (via TCM) so the local ReplicaGroups reflects the current placement before calling forRange/forToken
  2. Verify the token actually belongs to one of the ranges in the ReplicaGroups instance (e.g. check ranges.first/last bounds) before querying
  3. If this occurs during bootstrap/decommission, re-run the placement computation so ranges are split for all new tokens first
  4. Check for version skew: restart nodes or ensure all nodes see the same metadata epoch

Example fix

// before
VersionedEndpoints.ForRange endpoints = metadata.placements().forToken(token);
// after
if (metadata.placements().asMap().keySet().stream().noneMatch(r -> r.contains(token)))
    throw new IllegalArgumentException("token not covered by placements: " + token);
VersionedEndpoints.ForRange endpoints = metadata.placements().forToken(token);
Defensive patterns

Strategy: validation

Validate before calling

boolean covered = metadata.placements().asMap().keySet().stream().anyMatch(r -> r.contains(token));
if (!covered) throw new IllegalArgumentException("token not covered by placements: " + token);

Try / catch

try { VersionedEndpoints.ForRange e = replicaGroups.forToken(token); } catch (IllegalStateException e) { /* refresh metadata and retry once */ }

Prevention

When it happens

Trigger: Calling forRange(token) or forToken(token) with a token that is not covered by any range in the ReplicaGroups object; commonly happens during token movement/bootstrap when placement metadata is stale or when querying a token outside the ring ranges known to this node.

Common situations: A node requests ownership for a token that was just added or removed but its local TCM metadata has not caught up; a bootstrap/replace plan computes ranges over an outdated ClusterMetadata snapshot; splitRangesForPlacement input validation was bypassed with tokens outside placement bounds.

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 apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/47c84d5585ae296d. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/tcm/ownership/ReplicaGroups.java:162

        Epoch lastModified = Epoch.EMPTY;
        // find a range containing the *right* token for the given range - Range is start exclusive so if we looked for the
        // left one we could get the wrong range
        int pos = ordering.binarySearchAsymmetric(ranges, range.right, AsymmetricOrdering.Op.CEIL);
        if (pos >= 0 && pos < ranges.size() && ranges.get(pos).contains(range))
        {
            VersionedEndpoints.ForRange eps = endpoints.get(pos);
            lastModified = eps.lastModified();
            builder.addAll(eps.get(), ReplicaCollection.Builder.Conflict.ALL);
        }
        return VersionedEndpoints.forRange(lastModified, builder.build());
    }

    public VersionedEndpoints.ForRange forRange(Token token)
    {
        int pos = ordering.binarySearchAsymmetric(ranges, token, AsymmetricOrdering.Op.CEIL);
        if (pos >= 0 && pos < endpoints.size())
            return endpoints.get(pos);
        throw new IllegalStateException("Could not find range for token " + token + " in ReplicaGroups: " + this);
    }

    public VersionedEndpoints.ForToken forToken(Token token)
    {
        return forRange(token).forToken(token);
    }

    public Delta difference(NodeIdLookup idLookup, ReplicaGroups next)
    {
        Multimap<NodeId, ReplicaNode> oldMap = this.byNodeId(idLookup);
        Multimap<NodeId, ReplicaNode> newMap = next.byNodeId(idLookup);
        return new NodeIdDelta(diff(oldMap, newMap), diff(newMap, oldMap));
    }

    private Multimap<NodeId, ReplicaNode> byNodeId(NodeIdLookup idLookup)
    {
        ImmutableMultimap.Builder<NodeId, ReplicaNode> builder = ImmutableMultimap.builder();
        for (int i = 0; i < endpoints.size(); i++)

View on GitHub (pinned to 88fd0f6a0e)