apache/cassandra · error · IllegalStateException
Failed to find endpoints to fetch
Error message
Failed to find endpoints to fetch
What it means
After RangeStreamer computes sources for a range and puts them into rangesToFetchWithPreferredEndpoints, it immediately reads the entry back with getIfPresent(). A null result means the multimap internally failed to retain the sources for that range — an internal invariant violation (e.g. conflict resolution discarding the entry), so it throws IllegalStateException.
Solutions
- Report/inspect for duplicate range entries causing Conflict.NONE resolution; upgrade to a fixed Cassandra version
- Retry the bootstrap/rebuild after restarting the node
- Check topology for overlapping tokens (e.g. from an interrupted move) and run a full repair to normalize token metadata
Defensive patterns
Strategy: try-catch
Try / catch
try { fetch(); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Failed to find endpoints to fetch")) { restartNodeAndRetry(); reportBug(e); } else throw e; } Prevention
- Keep Cassandra upgraded to current patch versions (this is an internal invariant check)
- Avoid interrupted move/decommission states; complete or roll back operations
- Run `nodetool repair` after any failed streaming operation
When it happens
Trigger: calculateRangesToFetchWithPreferredEndpoints(): rangesToFetchWithPreferredEndpoints.putAll(toFetch, sources, Conflict.NONE) is immediately followed by a null getIfPresent(toFetch) — should be unreachable in normal operation; reachable only via logic bugs or conflicting duplicate range entries resolved to NONE.
Common situations: Encountered during streaming bootstrap/rebuild with overlapping range entries conflicting (NONE conflict policy dropping both); typically indicates a bug or unusual topology causing duplicate range submissions.
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
- Bad CMS state:
- A node required to move the data consistently is down
- All indexed columns should be included into the column…
- All values must be either negative or positive, got
- Bad node state
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/6bc19d91586bc625.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/dht/RangeStreamer.java:553
}
else
{
//Without strict consistency we have given up on correctness so no point in fetching from
//a random full + transient replica since it's also likely to lose data
//Also apply testSourceFilters that were given to us so we can safely select a single source
sources = sorted.apply(movements.get(params).get(toFetch).filter(and(isSufficient, testSourceFilters)));
//Limit it to just the first possible source, we don't need more than one and downstream
//will fetch from every source we supply
sources = sources.size() > 0 ? sources.subList(0, 1) : sources;
}
// storing range and preferred endpoint set
rangesToFetchWithPreferredEndpoints.putAll(toFetch, sources, Conflict.NONE);
logger.debug("Endpoints to fetch for {} are {}", toFetch, sources);
EndpointsForRange addressList = rangesToFetchWithPreferredEndpoints.getIfPresent(toFetch);
if (addressList == null)
throw new IllegalStateException("Failed to find endpoints to fetch " + toFetch);
/*
* When we move forwards (shrink our bucket) we are the one losing a range and no one else loses
* from that action (we also don't gain). When we move backwards there are two people losing a range. One is a full replica
* and the other is a transient replica. So we must need fetch from two places in that case for the full range we gain.
* For a transient range we only need to fetch from one.
*/
if (useStrictConsistency && addressList.size() > 1 && (addressList.filter(Replica::isFull).size() > 1 || addressList.filter(Replica::isTransient).size() > 1))
throw new IllegalStateException(String.format("Multiple strict sources found for %s, sources: %s", toFetch, addressList));
//We must have enough stuff to fetch from
if (!any(addressList, isSufficient))
{
if (strat.getReplicationFactor().allReplicas == 1)
{
if (useStrictConsistency)
{
logger.warn("A node required to move the data consistently is down");View on GitHub (pinned to 88fd0f6a0e)