{"record":{"id":"4b0ee66610c19815","repo":"apache/cassandra","slug":"bad-nodestate","errorCode":null,"errorMessage":"Bad NodeState ","messagePattern":"Bad NodeState ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/compatibility/GossipHelper.java","lineNumber":186,"sourceCode":"                break;\n            case MOVING:\n                sequence = metadata.inProgressSequences.get(nodeId);\n                if (!(sequence instanceof Move))\n                {\n                    logger.error(String.format(\"Cannot construct gossip state. Node is in %s state, but sequence the is %s\", NodeState.MOVING, sequence));\n                    return null;\n                }\n                Collection<Token> moveTokens = getTokensFromOperation(sequence);\n                if (!moveTokens.isEmpty())\n                {\n                    Token token = ((Move) sequence).tokens.iterator().next();\n                    status = valueFactory.moving(token);\n                }\n                break;\n            case REGISTERED:\n                break;\n            default:\n                throw new RuntimeException(\"Bad NodeState \" + nodeState);\n        }\n        return status;\n    }\n\n    public static Collection<Token> getTokensFromOperation(NodeId nodeId, ClusterMetadata metadata)\n    {\n        return getTokensFromOperation(metadata.inProgressSequences.get(nodeId));\n    }\n\n    public static Collection<Token> getTokensFromOperation(MultiStepOperation<?> sequence)\n    {\n        if (null == sequence)\n            return Collections.emptySet();\n\n        if (sequence.kind() == MultiStepOperation.Kind.JOIN)\n            return new HashSet<>(((BootstrapAndJoin)sequence).finishJoin.tokens);\n        else if (sequence.kind() == MultiStepOperation.Kind.REPLACE)\n            return new HashSet<>(((BootstrapAndReplace)sequence).bootstrapTokens);","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/compatibility/GossipHelper.java#L168-L204","documentation":"GossipHelper.nodeStateToStatus converts legacy gossip NodeState values into VersionedValue statuses during gossip-to-TCM upgrade; the default branch throws RuntimeException because a NodeState outside the handled set cannot be represented, indicating an unanticipated state during upgrade.","triggerScenarios":"Running the gossip compatibility/upgrade path with an endpoint whose NodeState is not one of the explicitly handled values (e.g. LEFT-ish, future/unknown enum value) when translating to a gossip status.","commonSituations":"Mixed-version upgrade where a newer node advertises a NodeState this node's code doesn't know; corrupted endpoint state; attempting upgrade with an unsupported intermediate version.","solutions":["Upgrade all nodes so every member understands each other's NodeState values","Check which node/state triggered it in logs; if it's a leftover dead node, remove it from the cluster before the TCM migration","Ensure the pre-upgrade Cassandra version is a supported migration baseline","Report/patch: extend nodeStateToStatus with the missing NodeState case if it's a legitimate state"],"exampleFix":"// before\ndefault:\n    throw new RuntimeException(\"Bad NodeState \" + nodeState);\n// after\ncase UNKNOWN_NEW_STATE: // e.g. added in a later version\n    status = valueFactory.normal(Collections.emptySet());\n    break;\ndefault:\n    throw new RuntimeException(\"Bad NodeState \" + nodeState);","handlingStrategy":"try-catch","validationCode":"// pre-upgrade check\nfor (EndpointState es : gossipStates)\n    assert knownNodeStates.contains(es.getNodeState()) : \"unknown NodeState during upgrade\";","typeGuard":null,"tryCatchPattern":"try { GossipHelper.nodeStateToStatus(nodeState, valueFactory); }\ncatch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Bad NodeState\")) { /* upgrade version or remove stale node */ }\n    else throw e;\n}","preventionTips":["Upgrade to a uniform gossip-compat version across the cluster before TCM migration","Purge dead/stale endpoints before upgrade","Avoid mixed-version upgrades spanning unsupported baselines"],"tags":["gossip","upgrade","tcm","compatibility"],"backgroundTag":"invalid-enum-value","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"}