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
- Refresh ClusterMetadata (via TCM) so the local ReplicaGroups reflects the current placement before calling forRange/forToken
- Verify the token actually belongs to one of the ranges in the ReplicaGroups instance (e.g. check ranges.first/last bounds) before querying
- If this occurs during bootstrap/decommission, re-run the placement computation so ranges are split for all new tokens first
- 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
- Always read placements from a fresh ClusterMetadata snapshot before token lookups
- After any token operation (bootstrap/replace/move), wait for the metadata epoch to catch up locally
- Validate proposed tokens against current range bounds before placement APIs
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
- Can only initialize cluster identifier during epoch
- Can't revert join from
- Can't revert replacement from
- Got overlapping ranges in replica groups:
- Illegal state:
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)