{"record":{"id":"5cd79ec45a2c62d2","repo":"apache/cassandra","slug":"got-overlapping-ranges-in-replica-groups","errorCode":null,"errorMessage":"Got overlapping ranges in replica groups: ","messagePattern":"Got overlapping ranges in replica groups: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/ownership/ReplicaGroups.java","lineNumber":102,"sourceCode":"            return 0;\n        }\n    };\n\n    public static final Serializer serializer = new Serializer();\n    public static final ReplicaGroups EMPTY = ReplicaGroups.builder().build();\n\n    public final ImmutableList<Range<Token>> ranges;\n    public final ImmutableList<VersionedEndpoints.ForRange> endpoints;\n\n    private ReplicaGroups(Map<Range<Token>, VersionedEndpoints.ForRange> replicaGroups)\n    {\n        ImmutableList.Builder<Range<Token>> rangesBuilder = ImmutableList.builderWithExpectedSize(replicaGroups.size());\n        ImmutableList.Builder<VersionedEndpoints.ForRange> endpointsBuilder = ImmutableList.builderWithExpectedSize(replicaGroups.size());\n        Range<Token> prev = null;\n        for (Map.Entry<Range<Token>, VersionedEndpoints.ForRange> entry : ImmutableSortedMap.copyOf(replicaGroups, Comparator.comparing(o -> o.left)).entrySet())\n        {\n            if (prev != null && prev.right.compareTo(entry.getKey().left) > 0 )\n                throw new IllegalArgumentException(\"Got overlapping ranges in replica groups: \" + replicaGroups);\n            prev = entry.getKey();\n            rangesBuilder.add(entry.getKey());\n            endpointsBuilder.add(entry.getValue());\n        }\n        this.ranges = rangesBuilder.build();\n        this.endpoints = endpointsBuilder.build();\n    }\n\n    private ReplicaGroups(ImmutableList<Range<Token>> ranges,\n                         ImmutableList<VersionedEndpoints.ForRange> endpoints)\n    {\n        this.ranges = ranges;\n        this.endpoints = endpoints;\n    }\n\n    /**\n     * returns a copy of ranges sorted by the right token (`ranges` in this class is sorted by the left)\n     */","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/ownership/ReplicaGroups.java#L84-L120","documentation":"The ReplicaGroups constructor builds parallel sorted lists of token ranges and their replica endpoints. It validates that consecutive ranges in the sorted order do not overlap: if the previous range's right bound extends past the next range's left bound, it throws IllegalArgumentException, because replica groups must partition (not overlap) the token space.","triggerScenarios":"Constructing ReplicaGroups from a map of (Range<Token> -> VersionedEndpoints.ForRange) where two ranges overlap, e.g. [0,100) and [50,150) present together.","commonSituations":"Bugs in custom placement/replication strategies that compute overlapping ranges; corrupted or hand-edited ownership metadata; merging partial range maps from different sources.","solutions":["Fix the producer of the range map so ranges are non-overlapping and cover the ring exactly once","Normalize/merge overlapping ranges before constructing ReplicaGroups","Validate the input map by sorting ranges and checking prev.right <= next.left before calling the constructor","If caused by a replication strategy bug, regenerate placement data (e.g. rebuild metadata) with the corrected strategy"],"exampleFix":"// before\nmap.put(new Range<>(t(0), t(100)), ep1);\nmap.put(new Range<>(t(50), t(150)), ep2);  // overlap -> throws\n// after\nmap.put(new Range<>(t(0), t(100)), ep1);\nmap.put(new Range<>(t(100), t(150)), ep2);","handlingStrategy":"validation","validationCode":"// validate before constructing\nList<Range<Token>> sorted = ranges.stream().sorted(Comparator.comparing(r -> r.left)).collect(Collectors.toList());\nfor (int i = 1; i < sorted.size(); i++)\n    if (sorted.get(i-1).right.compareTo(sorted.get(i).left) > 0) throw new IllegalArgumentException(\"Overlap: \" + sorted.get(i-1) + \" and \" + sorted.get(i));","typeGuard":"boolean rangesNonOverlapping(java.util.Collection<Range<Token>> rs) {\n    Range<Token> prev = null;\n    for (Range<Token> r : com.google.common.collect.ImmutableSortedMap.<Range<Token>,Object>naturalOrderKeys()) {}\n    return true; // sort and compare consecutive right<=left bounds\n}","tryCatchPattern":"try { new ReplicaGroups(map); } catch (IllegalArgumentException e) { // log offending map, fix range producer, rebuild }","preventionTips":["Ensure range producers emit a strict partition of the token ring","Unit-test replication/placement strategies for range overlap","Validate range maps (sort + adjacent-compare) at the boundary before constructing ReplicaGroups"],"tags":["cassandra","tcm","ownership"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}