{"record":{"id":"0a3fd371897cdb19","repo":"aeron-io/aeron","slug":"consensusmodule-context-clustermembers-must-be-set","errorCode":null,"errorMessage":"ConsensusModule.Context.clusterMembers must be set","messagePattern":"ConsensusModule\\.Context\\.clusterMembers must be set","errorType":"validation","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java","lineNumber":1772,"sourceCode":"                markFileDir = markFileDir.getCanonicalFile();\n\n                if (Strings.isEmpty(clusterServicesDirectoryName))\n                {\n                    clusterServicesDirectoryName = clusterDirectoryName;\n                }\n                else\n                {\n                    clusterServicesDirectoryName = new File(clusterServicesDirectoryName).getCanonicalPath();\n                }\n            }\n            catch (final IOException ex)\n            {\n                throw new UncheckedIOException(ex);\n            }\n\n            if (null == clusterMembers)\n            {\n                throw new ClusterException(\"ConsensusModule.Context.clusterMembers must be set\");\n            }\n\n            if (deleteDirOnStart)\n            {\n                IoUtil.delete(clusterDir, false);\n            }\n\n            IoUtil.ensureDirectoryExists(clusterDir, \"cluster\");\n            IoUtil.ensureDirectoryExists(markFileDir, \"mark file\");\n\n            if (startupCanvassTimeoutNs / leaderHeartbeatTimeoutNs < 2)\n            {\n                throw new ClusterException(\n                    \"startupCanvassTimeoutNs=\" + startupCanvassTimeoutNs +\n                    \" must be a multiple of leaderHeartbeatTimeoutNs=\" + leaderHeartbeatTimeoutNs);\n            }\n\n            if (null == clusterClock)","sourceCodeStart":1754,"sourceCodeEnd":1790,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java#L1754-L1790","documentation":"A ConsensusModule needs the full list of cluster member endpoints to canvas for a leader and form/maintain consensus. conclude() requires Context.clusterMembers to be explicitly set; a null value is a configuration error thrown as a ClusterException.","triggerScenarios":"Building a ConsensusModule.Context (or using the standalone-cluster launcher) without calling clusterMembers(...) before conclude().","commonSituations":"Omitting -Daeron.cluster.cluster.members on the command line; writing a custom main() that sets channels/ports but forgets clusterMembers; migrating from single-node setups that tolerated defaults in older Aeron versions.","solutions":["Call ctx.clusterMembers(\"memberId,clientFacingIngress,memberFacing,log,archive,events|...\"), e.g. \"0,localhost:20000,localhost:20001,localhost:20002,localhost:20003,localhost:20004\"","Set the system property aeron.cluster.cluster.members for the clusterio launcher","Use ClusterMembership tools or the same string on all members with consistent member IDs"],"exampleFix":"// before\nnew ConsensusModule.Context()\n    .ingressChannel(\"aeron:udp?endpoint=localhost:20000\"); // no clusterMembers\n// after\nnew ConsensusModule.Context()\n    .ingressChannel(\"aeron:udp?endpoint=localhost:20000\")\n    .clusterMembers(\"0,localhost:20000,localhost:20001,localhost:20002,localhost:20003,localhost:20004\");","handlingStrategy":"validation","validationCode":"if (ctx.clusterMembers() == null) {\n    throw new IllegalStateException(\"ConsensusModule.Context.clusterMembers must be set before conclude()\");\n}","typeGuard":null,"tryCatchPattern":"try { ctx.conclude(); } catch (ClusterException e) { if (e.getMessage().contains(\"clusterMembers must be set\")) { /* load cluster config and retry setup */ } }","preventionTips":["Centralize cluster member strings in one config source shared by all nodes","Validate the members string format (comma-separated six fields per member) before startup","Include clusterMembers in startup smoke tests"],"tags":["configuration","cluster","consensus"],"backgroundTag":"missing-required-config-field","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}