{"record":{"id":"6d953234a0c78166","repo":"apache/cassandra","slug":"unable-to-find-sufficient-sources-for-streaming-ra","errorCode":null,"errorMessage":"Unable to find sufficient sources for streaming range \" + trivialRange + \" in keyspace \" + keyspace","messagePattern":"Unable to find sufficient sources for streaming range \" \\+ trivialRange \\+ \" in keyspace \" \\+ keyspace","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"src/java/org/apache/cassandra/dht/RangeFetchMapCalculator.java","lineNumber":183,"sourceCode":"                // sort with the endpoint having the least number of streams first:\n                EndpointsForRange replicas = rangesWithSources.get(trivialRange)\n                        .sorted(Comparator.comparingInt(o -> optimisedMap.get(o.endpoint()).size()));\n                Replicas.temporaryAssertFull(replicas);\n                for (Replica replica : replicas)\n                {\n                    if (passFilters(replica, localDCCheck))\n                    {\n                        added = true;\n                        // if we pass filters, it means that we don't filter away localhost and we can count it as a source,\n                        // see RangeFetchMapCalculator#addEndpoints  and RangeStreamer#getRangeFetchMap\n                        if (replica.isSelf())\n                            continue; // but don't add localhost to avoid streaming locally\n                        fetchMap.put(replica.endpoint(), trivialRange);\n                        break;\n                    }\n                }\n                if (!added && !localDCCheck)\n                    throw new IllegalStateException(\"Unable to find sufficient sources for streaming range \" + trivialRange + \" in keyspace \" + keyspace);\n                if (!added)\n                    logger.info(\"Using other DC endpoints for streaming for range: {} and keyspace {}\", trivialRange, keyspace);\n                localDCCheck = false;\n            }\n        }\n        return fetchMap;\n    }\n    /*\n        Return the total number of range vertices in the graph\n     */\n    private int getTotalRangeVertices(MutableCapacityGraph<Vertex, Integer> graph)\n    {\n        int count = 0;\n        for (Vertex vertex : graph.getVertices())\n        {\n            if (vertex.isRangeVertex())\n            {\n                count++;","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/dht/RangeFetchMapCalculator.java#L165-L201","documentation":"RangeFetchMapCalculator.getRangeFetchMapForTrivialRanges() builds the streaming plan for bootstrap/rebuild by mapping each trivial (non-pending, naturally owned) range to a replica source. When no live replica in the local datacenter (and after fallback, the cluster) can serve a range, it throws IllegalStateException: the range cannot be streamed at all.","triggerScenarios":"Calling getRangeFetchMap (via RangeStreamer.fetch) during bootstrap/rebuild where a range's replicas are all filtered out (down nodes, source filters, or replicas absent from the local DC and localDCCheck fails).","commonSituations":"Bootstrapping a new node while required replicas are down; rebuilding a node in a DC that has no replica for the keyspace (NetworkTopologyStrategy missing the DC); RF configured smaller than needed in the source DC; aggressive snitch/endpoint filters excluding all sources.","solutions":["Bring the required replicas up and rerun bootstrap/rebuild (check `nodetool status` for down nodes)","If rebuilding in a new DC, ensure the keyspace uses NetworkTopologyStrategy with an RF > 0 for that DC (ALTER KEYSPACE ... WITH replication = {'class':'NetworkTopologyStrategy','dc1':3,'dc2':3})","Relax source filters or use nodetool with the appropriate source DC option (e.g. rebuild -- <source_dc>) so valid sources are considered","Run `nodetool cleanup`/repair after fixing replication to ensure data exists somewhere to stream from"],"exampleFix":"// before\nALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3};\n// after\nALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3,'dc2':3};","handlingStrategy":"validation","validationCode":"// Before rebuild/bootstrap, confirm sources exist in local DC\nKeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspace);\nReplicationFactor rf = ks.params.replication.asStrategy().getReplicationFactor(dc);\nif (rf.allReplicas == 0) throw new IllegalArgumentException(\"Keyspace \" + keyspace + \" has no replicas in DC \" + dc);","typeGuard":null,"tryCatchPattern":"try { streamer.fetch(); } catch (IllegalStateException e) { if (e.getMessage().contains(\"Unable to find sufficient sources\")) { verifyReplicasUp(); fixReplication(); } else throw e; }","preventionTips":["Check `nodetool status` for down nodes before bootstrap/rebuild","Ensure NetworkTopologyStrategy has RF > 0 for every DC involved","Run repair after changing replication factors"],"tags":["streaming","bootstrap","replication","topology"],"backgroundTag":"resource-not-found","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}