apache/cassandra · critical · IllegalStateException
Necessary replicas for strict consistency were removed by so
Error message
Necessary replicas for strict consistency were removed by source filters:
What it means
In RangeStreamer.calculateRangesToFetchWithPreferredEndpoints(), when strict consistency is enabled (useStrictConsistency, required for consistent bootstrap with transient replication), the replicas needed for strict correctness must survive the user-supplied source filters. If the filters would exclude any required strict replica, it throws IllegalStateException because streaming from the remaining sources would violate consistency.
Source
Thrown at src/java/org/apache/cassandra/dht/RangeStreamer.java:520
//Ultimately we populate this with whatever is going to be fetched from to satisfy toFetch
//It could be multiple endpoints and we must fetch from all of them if they are there
//With transient replication and strict consistency this is to get the full data from a full replica and
//transient data from the transient replica losing data
EndpointsForRange sources;
//Due to CASSANDRA-5953 we can have a higher RF than we have endpoints.
//So we need to be careful to only be strict when endpoints == RF
boolean isStrictConsistencyApplicable = useStrictConsistency && (movements.get(params).get(toFetch).size() == strat.getReplicationFactor().allReplicas);
if (isStrictConsistencyApplicable)
{
EndpointsForRange strictEndpoints = strictMovements.get(params).get(toFetch);
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 fromView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove or broaden the source filter so all required strict replicas are eligible sources (e.g. rebuild without restricting to one DC)
- Bring the filtered-out replicas up so they pass the filters, then retry
- Disable strict consistency if it's acceptable to risk missing data during the operation (understand the tradeoff with transient replication)
Example fix
// before nodetool rebuild -- dc1 # filter excludes replicas needed for strict consistency // after nodetool rebuild # no DC restriction, all replicas eligible
Defensive patterns
Strategy: try-catch
Validate before calling
if (useStrictConsistency && !all(strictEndpoints, testSourceFilters))
throw new IllegalStateException("Source filters conflict with strict consistency for " + toFetch); Try / catch
try { streamer.fetch(); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Necessary replicas for strict consistency were removed by source filters")) { relaxSourceFilters(); retry(); } else throw e; } Prevention
- Don't combine strict consistency with DC/host-restricted source filters unless all replicas are in scope
- Verify replica liveness before starting strict streaming
- Prefer rebuilding with no --source-dc restriction when strict consistency is on
When it happens
Trigger: fetchMap() with useStrictConsistency=true where testSourceFilters rejects one of the strictEndpoints required for a range — e.g. a source filter restricting streaming to a DC/host set that doesn't contain all necessary replicas for a range.
Common situations: nodetool bootstrap/rebuild with a source-DC filter while strict consistency is on; decommission/replace workflows where an obligated replica is down and filtered out; ops scripts using --source-options that conflict with strict consistency requirements.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Couldn't find any matching sufficient replica out of
- 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/29d5fc03105654d3.
Report an issue: GitHub.