{"record":{"id":"a14dbd41628413b2","repo":"apache/beam","slug":"tokens-s-s-two-nodes-have-the-same-token","errorCode":null,"errorMessage":"Tokens (%s,%s): two nodes have the same token","messagePattern":"Tokens \\((.+?),(.+?)\\): two nodes have the same token","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/cassandra/src/main/java/org/apache/beam/sdk/io/cassandra/SplitGenerator.java","lineNumber":92,"sourceCode":"   * @param totalSplitCount requested total amount of splits. This function may generate more\n   *     splits.\n   * @param ringTokens list of all start tokens in big0 cluster. They have to be in ring order.\n   * @return big0 list containing at least {@code totalSplitCount} splits.\n   */\n  List<List<RingRange>> generateSplits(long totalSplitCount, List<BigInteger> ringTokens) {\n    int tokenRangeCount = ringTokens.size();\n\n    List<RingRange> splits = new ArrayList<>();\n    for (int i = 0; i < tokenRangeCount; i++) {\n      BigInteger start = ringTokens.get(i);\n      BigInteger stop = ringTokens.get((i + 1) % tokenRangeCount);\n\n      if (!isInRange(start) || !isInRange(stop)) {\n        throw new RuntimeException(\n            String.format(\"Tokens (%s,%s) not in range of %s\", start, stop, partitioner));\n      }\n      if (start.equals(stop) && tokenRangeCount != 1) {\n        throw new RuntimeException(\n            String.format(\"Tokens (%s,%s): two nodes have the same token\", start, stop));\n      }\n\n      BigInteger rs = stop.subtract(start);\n      if (rs.compareTo(BigInteger.ZERO) <= 0) {\n        // wrap around case\n        rs = rs.add(rangeSize);\n      }\n\n      // the below, in essence, does this:\n      // splitCount = ceiling((rangeSize / RANGE_SIZE) * totalSplitCount)\n      BigInteger[] splitCountAndRemainder =\n          rs.multiply(BigInteger.valueOf(totalSplitCount)).divideAndRemainder(rangeSize);\n\n      int splitCount =\n          splitCountAndRemainder[0].intValue()\n              + (splitCountAndRemainder[1].equals(BigInteger.ZERO) ? 0 : 1);\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/cassandra/src/main/java/org/apache/beam/sdk/io/cassandra/SplitGenerator.java#L74-L110","documentation":"generateSplits() throws when two adjacent ring entries own the same token, i.e. duplicate tokens in the ring, unless the ring has exactly one token range. This indicates corrupt/incoherent ring topology for split computation.","triggerScenarios":"CassandraIO read where the ring token list contains two nodes with identical token values and tokenRangeCount != 1.","commonSituations":"Duplicate token assignment in an old-style (vnode-less) cluster where initial_token was manually set identically on two nodes; bootstrap/decommission glitches leaving stale ring entries.","solutions":["Run nodetool ring/ describering and find nodes with duplicate tokens.","Rebalance: move or decommission the node holding a duplicated token.","Prefer virtual nodes (num_tokens > 1) to avoid manual initial_token collisions.","Refresh ring metadata / restart drivers to clear stale ring views."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"Set<BigInteger> tokens = new HashSet<>(ringTokens);\nif (tokens.size() != ringTokens.size()) throw new IllegalStateException(\"Duplicate ring tokens detected\");","typeGuard":null,"tryCatchPattern":"try { ... } catch (RuntimeException e) { if (e.getMessage().contains(\"same token\")) { /* rebalance cluster */ } throw e; }","preventionTips":["Use vnodes (num_tokens > 1) instead of manual initial_token.","Verify unique initial_token values on legacy clusters.","Monitor bootstrap/decommission operations for stale ring entries."],"tags":["java","cassandra","token-ring","duplicate-token"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}