{"record":{"id":"dc52996602c80382","repo":"apache/cassandra","slug":"no-nodes-present-in-the-cluster-has-this-node-fin","errorCode":null,"errorMessage":"No nodes present in the cluster. Has this node finished starting up?","messagePattern":"No nodes present in the cluster\\. Has this node finished starting up\\?","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/dht/Murmur3Partitioner.java","lineNumber":445,"sourceCode":"    private long normalize(long v)\n    {\n        // We exclude the MINIMUM value; see getToken()\n        return v == Long.MIN_VALUE ? Long.MAX_VALUE : v;\n    }\n\n    public boolean preservesOrder()\n    {\n        return false;\n    }\n\n    public Map<Token, Float> describeOwnership(List<Token> sortedTokens)\n    {\n        Map<Token, Float> ownerships = new HashMap<Token, Float>();\n        Iterator<Token> i = sortedTokens.iterator();\n\n        // 0-case\n        if (!i.hasNext())\n            throw new RuntimeException(\"No nodes present in the cluster. Has this node finished starting up?\");\n        // 1-case\n        if (sortedTokens.size() == 1)\n            ownerships.put(i.next(), 1.0F);\n        // n-case\n        else\n        {\n            final BigInteger ri = BigInteger.valueOf(MAXIMUM).subtract(BigInteger.valueOf(MINIMUM.token + 1));  //  (used for addition later)\n            final BigDecimal r  = new BigDecimal(ri);\n            Token start = i.next();BigInteger ti = BigInteger.valueOf(((LongToken)start).token);  // The first token and its value\n            Token t; BigInteger tim1 = ti;                                                                // The last token and its value (after loop)\n\n            while (i.hasNext())\n            {\n                t = i.next(); ti = BigInteger.valueOf(((LongToken) t).token); // The next token and its value\n                float age = new BigDecimal(ti.subtract(tim1).add(ri).mod(ri)).divide(r, 6, BigDecimal.ROUND_HALF_EVEN).floatValue(); // %age = ((T(i) - T(i-1) + R) % R) / R\n                ownerships.put(t, age);                           // save (T(i) -> %age)\n                tim1 = ti;                                        // -> advance loop\n            }","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/dht/Murmur3Partitioner.java#L427-L463","documentation":"Murmur3Partitioner.describeOwnership(sortedTokens) computes ownership fractions by walking the sorted token ring; an empty ring means no tokens/nodes are registered, so ownership cannot be computed and it throws RuntimeException asking whether the node finished starting up. It reflects a cluster view with zero endpoints rather than a caller mistake in arguments.","triggerScenarios":"Calling describeOwnership (directly or via StorageService 'describeOwnership'/nodetool toppartitions-adjacent ownership queries) before gossip has populated token metadata, on a freshly started single node, or after a join failure leaving the ring empty.","commonSituations":"Monitoring scripts querying ownership immediately after node start; nodetool run before the node joined the ring; tests constructing a partitioner without registering any tokens; a cluster whose schema/token metadata hasn't loaded.","solutions":["Wait for the node to finish startup and join the ring (nodetool status shows the node UP) before querying ownership.","Pass a non-empty sortedTokens collection when calling describeOwnership programmatically.","In tests, seed TokenMetadata with at least one token before calling describeOwnership.","Investigate join/bootstrap failures (logs) if the cluster should have nodes but the ring is empty."],"exampleFix":"// before\nMap<Token, Float> ownership = partitioner.describeOwnership(tokenMetadata.sortedTokens());\n// after\nCollection<Token> sorted = tokenMetadata.sortedTokens();\nif (sorted.isEmpty()) {\n    logger.warn(\"Ring is empty; node not yet joined. Skipping ownership query.\");\n    return;\n}\nMap<Token, Float> ownership = partitioner.describeOwnership(sorted);","handlingStrategy":"try-catch","validationCode":"Collection<Token> sorted = tokenMetadata.sortedTokens();\nif (sorted == null || sorted.isEmpty()) {\n    logger.warn(\"No tokens in ring; node may still be starting.\");\n    return Collections.emptyMap();\n}","typeGuard":"boolean ringIsPopulated(TokenMetadata tm) { return !tm.sortedTokens().isEmpty(); }","tryCatchPattern":"try {\n    return partitioner.describeOwnership(tokenMetadata.sortedTokens());\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"No nodes present\")) return Collections.emptyMap(); // node still joining\n    throw e;\n}","preventionTips":["Wait for nodetool status to show the node UP/normal before ownership queries.","Add retry/backoff in monitoring scripts around startup.","In tests, seed TokenMetadata with tokens before asserting ownership."],"tags":["partitioner","token-metadata","startup","empty-collection"],"backgroundTag":"empty-required-field","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"}