apache/cassandra · error · IllegalStateException

Couldn't find any matching sufficient replica out of: ->

Error message

Couldn't find any matching sufficient replica out of:  -> 

What it means

While building the movement map for a move, for each range being lost by a strict source, the code needs another sufficient replica within the same range as a streaming source. If no matching replica can be added and consistency is strict, it throws IllegalStateException; otherwise it flags needsRelaxedSources to fall back to relaxed source selection. It protects against streaming data from replicas that don't actually hold the range.

Solutions

  1. Run a repair (nodetool repair) to ensure other replicas actually hold the range, then retry the move
  2. Increase the replication factor or bring up additional replicas for the affected ranges
  3. Run the move without strict consistency only after confirming data availability (relaxed mode risks stale data)
  4. Bring previously-down replicas back online so a valid source exists

Example fix

// before
// move attempted with RF=1 and other replica down
// after
// nodetool repair <keyspace>; nodetool status to confirm live replicas; then nodetool move
Defensive patterns

Strategy: validation

Validate before calling

for (Range<Token> range : movingRanges)
    if (liveReplicasHolding(range).size() < 2)
        throw new IllegalStateException("No sufficient replica available for " + range);

Try / catch

try { move.execute(); } catch (IllegalStateException e) { logger.error("No valid streaming source: {}", e.getMessage()); scheduleRepairAndRetry(); }

Prevention

When it happens

Trigger: movementMap finds a strictConsistency source candidate whose range matches the destination range but whose endpoint equals the destination, or no candidate passes sources.addSource(); thrown when strict consistency is required and no valid replica exists for the range.

Common situations: Insufficient replication factor for the moved range (RF too low for the datacenter); other replicas of the range are down so no live source exists; moving a node in a single-replica range scenario.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/f3c03b7d15741989. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/tcm/sequences/Move.java:479

    {
        MovementMap.Builder allMovements = MovementMap.builder();
        toStart.forEach((params, delta) -> {
            RangesByEndpoint targets = delta.writes.additions(endpointLookup);
            ReplicaGroups oldOwners = placements.get(params).reads;
            EndpointsByReplica.Builder movements = new EndpointsByReplica.Builder();
            Iterable<Replica> replicaRemovals = midDeltas.get(params).reads.removals(endpointLookup).flattenValues();
            RangesByEndpoint writeAdditions = toSplitRanges.get(params).writes.additions(endpointLookup);
            targets.flattenValues().forEach(destination -> {
                SourceHolder sources = new SourceHolder(fd, destination, writeAdditions, strictConsistency);
                AtomicBoolean needsRelaxedSources = new AtomicBoolean();
                // first, try to find strict sources for the ranges we need to stream - these are the ranges that
                // instances are losing.
                replicaRemovals.forEach(strictSource -> {
                    if (strictSource.range().equals(destination.range()) && !strictSource.endpoint().equals(destination.endpoint()))
                        if (!sources.addSource(strictSource))
                        {
                            if (!strictConsistency)
                                throw new IllegalStateException("Couldn't find any matching sufficient replica out of: " + strictSource + " -> " + destination);
                            needsRelaxedSources.set(true);
                        }
                });
                // if we are not running with strict consistency, try to find other sources for streaming
                if (needsRelaxedSources.get())
                {
                    for (Replica source : DatabaseDescriptor.getNodeProximity()
                                                            .sortedByProximity(FBUtilities.getBroadcastAddressAndPort(),
                                                                               oldOwners.forRange(destination.range()).get()))
                    {
                        if (fd.isAlive(source.endpoint()) && !source.endpoint().equals(destination.endpoint()))
                        {
                            if ((sources.fullSource == null && source.isFull()) ||
                                (sources.transientSource == null && source.isTransient()))
                                sources.addSource(source);
                        }
                    }
                }

View on GitHub (pinned to 88fd0f6a0e)