{"record":{"id":"e8b16644fdfe5d36","repo":"apache/cassandra","slug":"not-starting-client-transports-in-write-survey-mod","errorCode":null,"errorMessage":"Not starting client transports in write_survey mode as it's bootstrapping or auth is enabled","messagePattern":"Not starting client transports in write_survey mode as it's bootstrapping or auth is enabled","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/CassandraDaemon.java","lineNumber":910,"sourceCode":"    {\n        DatabaseDescriptor.daemonInitialization();\n    }\n\n    public void validateTransportsCanStart()\n    {\n        ClusterMetadata metadata = ClusterMetadata.current();\n        MultiStepOperation<?> startupSequence = metadata.inProgressSequences.get(metadata.myNodeId());\n\n        // We only start transports if bootstrap has completed, and we're not in survey mode, OR if we are in\n        // survey mode and streaming has completed, but we're not using auth.\n        // OR if we have not joined the ring yet.\n        if (startupSequence != null)\n        {\n            if (StorageService.instance.isSurveyMode())\n            {\n                if (!StorageService.instance.readyToFinishJoiningRing() || DatabaseDescriptor.isAuthenticationRequired())\n                {\n                    throw new IllegalStateException(\"Not starting client transports in write_survey mode as it's bootstrapping or \" +\n                                                    \"auth is enabled\");\n                }\n            }\n            else\n            {\n                throw new IllegalStateException(\"Node is not yet bootstrapped completely\");\n            }\n        }\n        else\n        {\n            // Bootstrap with same address is an edge-case here, since we rely on HIBERNATE to prevent writes\n            // toward the bootstrapping replacement, so there's no startup sequence involved.\n            if (StorageService.isReplacingSameAddress() && StorageService.instance.isSurveyMode())\n                return;\n\n            // This node has not joined the ring (i.e. it was started with -Dcassandra.join_ring=false)\n            if (StorageService.instance.isStarting())\n                return;","sourceCodeStart":892,"sourceCodeEnd":928,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/CassandraDaemon.java#L892-L928","documentation":"CassandraDaemon refuses to start client transports (native transport, etc.) while the node is in write_survey mode but has not finished its bootstrap/repair phase, or while authentication is required but not yet fully initialized. In write_survey mode a node receives writes but does not back-propagate them, so exposing client traffic before the ring join completes (or before auth is ready) would silently lose or fail writes. The check lives in validateTransportsCanStart and throws IllegalStateException.","triggerScenarios":"Calling start() or startNativeTransport() on a node started with -Dcassandra.write_survey=true while StorageService.readyToFinishJoiningRing() is false, or while DatabaseDescriptor.isAuthenticationRequired() is true (authenticator configured but the node hasn't completed its startup sequence).","commonSituations":"Operators boot new datacenters in write_survey mode for DC expansion and try to start the node or enable native transport before bootstrap/repair finished; nodes with PasswordAuthenticator enabled started in survey mode before role setup is complete.","solutions":["Wait until bootstrap/repair (readyToFinishJoiningRing) completes before calling startNativeTransport / letting start() proceed; check with nodetool netstats/repair status.","If auth is the blocker, complete role/auth setup (e.g. create superuser roles) or temporarily start with a allow-all authenticator in survey mode.","If the node was accidentally started in write_survey mode, restart without -Dcassandra.write_survey so the normal startup sequence runs.","Complete the survey-phase join explicitly (resume join) once the survey is done, then start transports."],"exampleFix":"// before: scripts/start.sh\nbin/cassandra -Dcassandra.write_survey=true && nodetool startnativetransport\n// after\nbin/cassandra -Dcassandra.write_survey=true\n# wait until readyToFinishJoiningRing (nodetool netstats shows normal), then:\nnodetool resume && nodetool startnativetransport","handlingStrategy":"validation","validationCode":"if (StorageService.instance.isSurveyMode() && (!StorageService.instance.readyToFinishJoiningRing() || DatabaseDescriptor.isAuthenticationRequired())) {\n    throw new IllegalStateException(\"Defer client transports until survey bootstrap completes\");\n}","typeGuard":null,"tryCatchPattern":"try { daemon.startNativeTransport(); } catch (IllegalStateException e) { logger.warn(\"Transports deferred: {}\", e.getMessage()); /* retry after ring join */ }","preventionTips":["Check `nodetool netstats`/join status before enabling native transport in survey mode","Automate the survey->resume->start-transport sequence in orchestration scripts","Remember auth-enabled nodes cannot start transports in write_survey; complete role setup first"],"tags":["cassandra","startup","write-survey","bootstrap"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}