{"record":{"id":"353e7f4ce30a5546","repo":"apache/cassandra","slug":"cannot-achieve-consistency-level-s-for-batchlog-i","errorCode":null,"errorMessage":"Cannot achieve consistency level %s for batchlog in local DC, required:2, available:0","messagePattern":"Cannot achieve consistency level (.+?) for batchlog in local DC, required:2, available:0","errorType":"exception","errorClass":"UnavailableException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/locator/ReplicaPlans.java","lineNumber":332,"sourceCode":"        //  - choose min(2, number of qualifying candiates above)\n        //  - allow the local node to be the only replica only if it's a single-node DC\n        Collection<InetAddressAndPort> chosenEndpoints = filterBatchlogEndpoints(false,\n                                                                                 local.rack,\n                                                                                 localEndpoints,\n                                                                                 Collections::shuffle,\n                                                                                 (r) -> FailureDetector.isEndpointAlive.test(r) && metadata.directory.peerState(r) == NodeState.JOINED,\n                                                                                 ThreadLocalRandom.current()::nextInt);\n\n        // Batchlog is hosted by either one node or two nodes from different racks.\n        ConsistencyLevel consistencyLevel = chosenEndpoints.size() == 1 ? ConsistencyLevel.ONE : ConsistencyLevel.TWO;\n\n        if (chosenEndpoints.isEmpty())\n        {\n            if (isAny)\n                chosenEndpoints = Collections.singleton(FBUtilities.getBroadcastAddressAndPort());\n            else\n                // UnavailableException instead of letting the batchlog write unnecessarily timeout\n                throw new UnavailableException(\"Cannot achieve consistency level \" + consistencyLevel\n                        + \" for batchlog in local DC, required:\" + REQUIRED_BATCHLOG_REPLICA_COUNT\n                        + \", available:\" + 0,\n                        consistencyLevel, REQUIRED_BATCHLOG_REPLICA_COUNT, 0);\n        }\n\n        return ReplicaLayout.forTokenWrite(Keyspace.open(SchemaConstants.SYSTEM_KEYSPACE_NAME).getReplicationStrategy(),\n                                           SystemReplicas.getSystemReplicas(chosenEndpoints).forToken(token),\n                                           EndpointsForToken.empty(token));\n    }\n\n    public static ReplicaPlan.ForWrite forBatchlogWrite(ClusterMetadata metadata, boolean isAny) throws UnavailableException\n    {\n        // A single case we write not for range or token, but multiple mutations to many tokens\n        Token token = DatabaseDescriptor.getPartitioner().getMinimumToken();\n        Keyspace systemKeyspace = Keyspace.open(SchemaConstants.SYSTEM_KEYSPACE_NAME);\n\n        ReplicaLayout.ForTokenWrite liveAndDown = liveAndDownForBatchlogWrite(token, metadata, isAny);\n        // Batchlog is hosted by either one node or two nodes from different racks.","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/locator/ReplicaPlans.java#L314-L350","documentation":"Batchlog writes require at least REQUIRED_BATCHLOG_REPLICA_COUNT (2) live batchlog endpoints in the local datacenter to meet the batchlog consistency level. When no suitable live endpoints exist in the local DC, ReplicaPlans throws this UnavailableException immediately rather than letting the write time out, telling you the CL cannot be achieved (required:2, available:0).","triggerScenarios":"Executing a logged batch (or any operation needing a batchlog write) when fewer than 2 batchlog-suitable replicas are alive in the local DC, e.g. with a single-node DC or after mass node failure/outage.","commonSituations":"Running a single-node cluster or 1-node DC while writing logged batches; nodes in the local DC down during a rolling upgrade; network partition isolating the local DC.","solutions":["Ensure at least 2 nodes are live in the local datacenter, or add nodes","Use unlogged batches only if safe, or reduce batch usage","Check node status with nodetool status and restore failed nodes/network connectivity"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"int liveInLocalDc = tokenMetadata.getSnapshot().getEndpoints(localDc).size();\nif (liveInLocalDc < 2) throw new IllegalStateException(\"Need >=2 live nodes in local DC for batchlog writes\");","typeGuard":null,"tryCatchPattern":"try { session.execute(batchStatement); }\ncatch (UnavailableException e) { if (e.getMessage().contains(\"batchlog\")) { /* back off and retry after nodes recover */ } }","preventionTips":["Keep at least 2 (ideally 3) nodes per DC that store the system keyspace","Monitor per-DC live node counts and alert before batchlog writes become impossible","Prefer unlogged batches or atomic batches where the batchlog is not required"],"tags":["consistency","batchlog","unavailable"],"backgroundTag":"insufficient-replicas-available","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"}