{"record":{"id":"27afb59d802fe38a","repo":"apache/cassandra","slug":"failed-to-find-first-cms-node-in-directory","errorCode":null,"errorMessage":"Failed to find first CMS node in directory","messagePattern":"Failed to find first CMS node in directory","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/ClusterMetadata.java","lineNumber":495,"sourceCode":"    public ClusterMetadata forceInitializedState(int clusterIdentifier,\n                                                 NodeAddresses addresses,\n                                                 NodeVersion version,\n                                                 Location location)\n    {\n        if (this.metadataIdentifier != EMPTY_METADATA_IDENTIFIER)\n            throw new IllegalStateException(String.format(\"Can only initialize cluster identifier once, but it was already set to %d\", this.metadataIdentifier));\n\n        if (clusterIdentifier == EMPTY_METADATA_IDENTIFIER)\n            throw new IllegalArgumentException(\"Can not initialize cluster with empty cluster identifier\");\n\n        if (this.epoch.isAfter(Epoch.FIRST))\n            throw new IllegalStateException(String.format(\"Can only initialize cluster identifier during epoch %d, but current epoch is %d\", Epoch.FIRST.getEpoch(), epoch.getEpoch()));\n\n        // Maybe register the first CMS node. If upgrading from gossip, this should be a no-op\n        Directory withRegistered = directory.with(addresses, location, version);\n        NodeId firstNode = withRegistered.peerId(addresses.broadcastAddress);\n        if (firstNode == null)\n            throw new IllegalStateException(\"Failed to find first CMS node in directory\");\n\n        CMSMembership initialCMS = cmsMembership.startJoining(firstNode).finishJoining(firstNode);\n        return new ClusterMetadata(clusterIdentifier,\n                                   epoch,\n                                   partitioner,\n                                   schema,\n                                   withRegistered,\n                                   tokenMap,\n                                   placements,\n                                   accordFastPath,\n                                   lockedRanges,\n                                   inProgressSequences,\n                                   consensusMigrationState,\n                                   extensions,\n                                   accordStaleReplicas,\n                                   initialCMS);\n    }\n","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/ClusterMetadata.java#L477-L513","documentation":"After registering the first node's addresses into the Directory, forceInitializedState() looks up the NodeId for the local broadcast address; a null result means the directory update did not produce a registered peer for the CMS seed node, which is an internal invariant failure.","triggerScenarios":"directory.with(addresses, location, version) returns a Directory whose peerId(addresses.broadcastAddress) is null — i.e. the local node's broadcast address does not match any registered peer after the update.","commonSituations":"Broadcast address misconfiguration (broadcast_address differs from the address actually registered), inconsistent node configuration during first-cluster bootstrap, or a bug/race in the directory registration path during upgrade from gossip.","solutions":["Check cassandra.yaml broadcast_address/broadcast_and_rpc_address match the address the node registers with.","Confirm the node's location and version arguments passed to forceInitializedState() are correct.","Retry bootstrap on a clean state; if reproducible, capture the directory contents and report a bug (invariant violation)."],"exampleFix":"// before\nDirectory withRegistered = directory.with(addresses, location, version);\nNodeId firstNode = withRegistered.peerId(addresses.broadcastAddress); // null\n// after\nDirectory withRegistered = directory.with(addresses, location, version);\nNodeId firstNode = withRegistered.peerId(addresses.broadcastAddress);\nif (firstNode == null)\n    throw new IllegalStateException(\"peerId null for \" + addresses.broadcastAddress + \"; check broadcast_address config\");","handlingStrategy":"validation","validationCode":"InetAddressAndPort bc = FBUtilities.getBroadcastAddressAndPort();\nif (directory.peerId(bc) == null && directory.with(addresses, location, version).peerId(bc) == null)\n    throw new IllegalStateException(\"Broadcast address \" + bc + \" not registerable in directory\");","typeGuard":null,"tryCatchPattern":"try {\n    cms.forceInitializedState(...);\n} catch (IllegalStateException e) {\n    logger.error(\"Directory registration failed; verify broadcast_address\", e);\n}","preventionTips":["Verify broadcast_address in cassandra.yaml matches the registered address","Ensure consistent node configuration during first bootstrap","Report recurring null peerId as a TCM bug"],"tags":["cassandra","tcm","directory","invariant"],"backgroundTag":"internal-invariant-violation","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"}