{"record":{"id":"59a60a6440bd4451","repo":"apache/cassandra","slug":"node-is-alive-and-owns-this-id-use-decommission","errorCode":null,"errorMessage":"Node  is alive and owns this ID. Use decommission command to remove it from the ring","messagePattern":"Node  is alive and owns this ID\\. Use decommission command to remove it from the ring","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/sequences/SingleNodeSequences.java","lineNumber":137,"sourceCode":"\n    /**\n     * Entrypoint to begin node removal process\n     *\n     * @param toRemove id of the node to remove\n     * @param force if set to true, will remove the node even if this would mean there will be not enough nodes\n     *              to satisfy replication factor\n     */\n    static void removeNode(NodeId toRemove, boolean force)\n    {\n        ClusterMetadata metadata = ClusterMetadata.current();\n        if (toRemove.equals(metadata.myNodeId()))\n            throw new UnsupportedOperationException(\"Cannot remove self\");\n        InetAddressAndPort endpoint = metadata.directory.endpoint(toRemove);\n        if (endpoint == null)\n            throw new UnsupportedOperationException(\"Host ID not found.\");\n        if (Gossiper.instance.getLiveMembers().contains(endpoint))\n            throw new UnsupportedOperationException(\"Node \" + endpoint + \" is alive and owns this ID. Use decommission command to remove it from the ring\");\n\n        NodeState removeState = metadata.directory.peerState(toRemove);\n        if (removeState == null)\n            throw new UnsupportedOperationException(\"Node to be removed is not a member of the token ring\");\n        if (removeState == NodeState.LEAVING)\n            logger.warn(\"Node {} is already leaving or being removed, continuing removal anyway\", endpoint);\n\n        if (metadata.inProgressSequences.contains(toRemove))\n            throw new UnsupportedOperationException(\"Can not remove a node that has an in-progress sequence\");\n\n        ReconfigureCMS.maybeReconfigureCMS(metadata, endpoint);\n\n        logger.info(\"starting removenode with {} {}\", metadata.epoch, toRemove);\n        Collection<Token> tokens  = metadata.tokenMap.tokens(toRemove);\n        ClusterMetadataService.instance().commit(new PrepareLeave(toRemove,\n                                                                  force,\n                                                                  ClusterMetadataService.instance().placementProvider(),\n                                                                  LeaveStreams.Kind.REMOVENODE));\n        InProgressSequences.finishInProgressSequences(toRemove);","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/sequences/SingleNodeSequences.java#L119-L155","documentation":"removeNode checks whether the endpoint owning the given host ID is currently in the Gossiper's live-member set; if it is, removal is refused with UnsupportedOperationException. A live node must not be force-removed from the ring; decommission performs a graceful leave instead, preserving data safety.","triggerScenarios":"Calling `nodetool removenode <hostId>` while the target node is up and sending gossip heartbeats — e.g. target is merely restarting, partially partitioned from this node, or fully healthy.","commonSituations":"Operator assumes a node is dead after a brief outage but it recovered; gossip is partitioned so the removal coordinator sees the node as live while others don't; mixed-up host IDs between two nodes.","solutions":["Verify the node is truly down (`nodetool gossipinfo`, ping the endpoint); if it is alive, run `nodetool decommission` on it instead.","If the node is actually running and healthy, decommission gracefully to move data off it.","If the node should be dead but gossips as live, stop the Cassandra process on the target and wait for it to be marked down, then re-run removenode.","Check for network partition causing stale liveness before forcing removal."],"exampleFix":"// before\nnodetool removenode 8f3e-...  // node still up\n// after\nif (!isEndpointAlive(deadNodeIp)) {\n    nodetool.removenode(hostId);\n} else {\n    // run on the target instead:\n    // nodetool decommission\n}","handlingStrategy":"validation","validationCode":"InetAddressAndPort endpoint = ClusterMetadata.current().directory.endpoint(NodeId.fromString(hostId));\nif (endpoint != null && Gossiper.instance.getLiveMembers().contains(endpoint))\n    throw new IllegalArgumentException(\"Node \" + endpoint + \" is alive; run decommission on it instead of removenode\");","typeGuard":null,"tryCatchPattern":"try {\n    storageService.removeNode(hostId);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"is alive and owns this ID\")) {\n        // target recovered or gossip stale; verify then decommission or wait for down\n        handleAliveTarget(e.getMessage());\n    } else throw e;\n}","preventionTips":["Verify the target is DOWN in `nodetool gossipinfo` from the coordinator before removenode.","Check for node restarts or network flaps during maintenance windows.","Use decommission for any node you can still log into.","After an asymmetric partition, run removal from a coordinator that sees the node as dead."],"tags":["removenode","gossip","live-node","decommission"],"backgroundTag":"invalid-argument-value","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"}