apache/cassandra · critical · IllegalStateException
Couldn't find any matching sufficient replica out of
Error message
Couldn't find any matching sufficient replica out of
What it means
RangeStreamer.calculateRangesToFetchWithPreferredEndpoints() requires, under strict consistency, at least one sufficient (full-data-capable) replica among the strict endpoints for each range. If none of the candidate strict replicas is sufficient to serve the full range, it throws IllegalStateException listing the replicas that were considered.
Source
Thrown at src/java/org/apache/cassandra/dht/RangeStreamer.java:532
if (strictEndpoints.stream().filter(Replica::isFull).count() > 1)
throw new AssertionError("Expected <= 1 endpoint but found " + strictEndpoints);
//We have to check the source filters here to see if they will remove any replicas
//required for strict consistency
if (!all(strictEndpoints, testSourceFilters))
throw new IllegalStateException("Necessary replicas for strict consistency were removed by source filters: " + buildErrorMessage(sourceFilters, strictEndpoints));
//If we are transitioning from transient to full and and the set of replicas for the range is not changing
//we might end up with no endpoints to fetch from by address. In that case we can pick any full replica safely
//since we are already a transient replica and the existing replica remains.
//The old behavior where we might be asked to fetch ranges we don't need shouldn't occur anymore.
//So it's an error if we don't find what we need.
if (strictEndpoints.isEmpty() && toFetch.isTransient())
throw new AssertionError("If there are no endpoints to fetch from then we must be transitioning from transient to full for range " + toFetch);
// we now add all potential strict endpoints when building the strictMovements, if we still have no full replicas for toFetch we should fail
if (!any(strictEndpoints, isSufficient))
throw new IllegalStateException("Couldn't find any matching sufficient replica out of " + buildErrorMessage(sourceFilters, movements.get(params).get(toFetch)));
sources = strictEndpoints;
}
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);
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Bring up the full replicas for the affected range and rerun the bootstrap/rebuild
- Run `nodetool repair` on the range/keyspace to restore a full replica before streaming
- Broaden source filters so a full replica is eligible
- Temporarily disable strict consistency if partial-data risk is acceptable
Defensive patterns
Strategy: validation
Validate before calling
if (strictEndpoints.stream().noneMatch(r -> r.isFull() && isSufficient.test(r)))
throw new IllegalStateException("No sufficient full replica for " + toFetch + "; run repair first"); Try / catch
try { streamer.fetch(); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Couldn't find any matching sufficient replica")) { runRepair(keyspace); retry(); } else throw e; } Prevention
- Keep at least one healthy full replica per range (avoid RF barely above transient losses)
- Run repair regularly with transient replication enabled
- Check replica liveness before initiating bootstrap
When it happens
Trigger: fetchMap() with useStrictConsistency=true where every candidate endpoint for a range fails the isSufficient predicate — typically all candidates are transient replicas or are filtered/down.
Common situations: Bootstrapping into a cluster where the only full replica for a range is down; transient replication setups where both full replicas are excluded by source filters; repair backlog leaving no healthy full replica to stream from.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Necessary replicas for strict consistency were removed by so
- Multiple strict sources found for %s, sources: %s
- A node required to move the data consistently is down
- Invalid value of stream_throughput_outbound:
- Invalid value of inter_dc_stream_throughput_outbound:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/f4bf47bfb5650e94.
Report an issue: GitHub.