apache/cassandra · error · IllegalStateException
Multiple strict sources found for %s, sources: %s
Error message
Multiple strict sources found for %s, sources: %s
What it means
With strict consistency enabled, a range must be fetched from at most one full and one transient source to preserve data correctness guarantees during range movements. If the computed address list contains more than one full or more than one transient strict source, RangeStreamer throws IllegalStateException because it cannot choose safely among multiple strict sources.
Source
Thrown at src/java/org/apache/cassandra/dht/RangeStreamer.java:562
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");
throw new IllegalStateException("Unable to find sufficient sources for streaming range " + toFetch + " in keyspace " + keyspace + " with RF=1. " +
"Ensure this keyspace contains replicas in the source datacenter.");
}
else
logger.warn("Unable to find sufficient sources for streaming range {} in keyspace {} with RF=1. " +
"Keyspace might be missing data.", toFetch, keyspace);
}
else
{View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Verify token metadata consistency with `nodetool describering` / `nodetool status`; resolve overlapping ranges (usually via repair + restart)
- Allow any in-flight move/decommission/bootstrap operations to complete before streaming, then retry
- If caused by a bug in range-movement bookkeeping, upgrade to a version with fixes to RangeStreamer strict handling
- Avoid mixing move and bootstrap operations concurrently on overlapping ranges
Defensive patterns
Strategy: try-catch
Validate before calling
// check for overlapping ownership before streaming
if (tokenMetadata.getPendingRanges(keyspace).size() > 0)
throw new IllegalStateException("Pending ranges exist; complete in-flight operations before strict streaming"); Try / catch
try { streamer.fetch(); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Multiple strict sources found")) { waitForOperationsToSettle(); retry(); } else throw e; } Prevention
- Serialize topology operations (no concurrent move+bootstrap)
- Validate ring consistency with describering before strict streaming
- Upgrade if reproducible — this signals bookkeeping anomalies
When it happens
Trigger: calculateRangesToFetchWithPreferredEndpoints() with useStrictConsistency=true and an addressList where filter(Replica::isFull).size() > 1 or filter(Replica::isTransient).size() > 1 for a single range.
Common situations: Complex range movement scenarios (move/decommission in flight) producing overlapping ownership; token metadata inconsistencies after failed operations; incorrect strict-consistency setting combined with unusual topology changes.
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
- Necessary replicas for strict consistency were removed by so
- Couldn't find any matching sufficient replica out of
- Source %s for %s is not remaining as a replica after the mov
- A node required to move the data consistently is down
- Invalid value of stream_throughput_outbound:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/080d887f4eb26526.
Report an issue: GitHub.