{"record":{"id":"1172b1f118981486","repo":"aeron-io/aeron","slug":"replicationchannel-must-be-set","errorCode":null,"errorMessage":"replicationChannel must be set","messagePattern":"replicationChannel must be set","errorType":"validation","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java","lineNumber":2093,"sourceCode":"                    .controlResponseChannel(AeronArchive.Configuration.localControlChannel())\n                    .controlRequestStreamId(AeronArchive.Configuration.localControlStreamId())\n                    .controlResponseStreamId(\n                        clusterId * 100 + 100 + AeronArchive.Configuration.controlResponseStreamId());\n            }\n\n            if (!archiveContext.controlRequestChannel().startsWith(CommonContext.IPC_CHANNEL))\n            {\n                throw new ClusterException(\"local archive control must be IPC\");\n            }\n\n            if (!archiveContext.controlResponseChannel().startsWith(CommonContext.IPC_CHANNEL))\n            {\n                throw new ClusterException(\"local archive control must be IPC\");\n            }\n\n            if (null == replicationChannel)\n            {\n                throw new ClusterException(\"replicationChannel must be set\");\n            }\n\n            archiveContext\n                .aeron(aeron)\n                .errorHandler(null) // ensure that exceptions are re-thrown\n                .ownsAeronClient(false)\n                .lock(NoOpLock.INSTANCE)\n                .controlRequestChannel(addAliasIfAbsent(\n                archiveContext.controlRequestChannel(),\n                \"cm-archive-ctrl-req-cluster-\" + clusterId + \"-member-\" + clusterMemberId))\n                .controlResponseChannel(addAliasIfAbsent(\n                archiveContext.controlResponseChannel(),\n                \"cm-archive-ctrl-resp-cluster-\" + clusterId + \"-member-\" + clusterMemberId))\n                .clientName(agentRoleName);\n\n            if (null == terminationHook)\n            {\n                terminationHook = () -> {};","sourceCodeStart":2075,"sourceCodeEnd":2111,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java#L2075-L2111","documentation":"The consensus module needs a replication channel for the archive to stream recording segments between cluster members. conclude() validates that the configured replicationChannel is non-null and throws ClusterException otherwise.","triggerScenarios":"ConsensusModule.Context.replicationChannel() was never set (null) at launch time — typically when building the context programmatically and omitting replicationChannel(...).","commonSituations":"Hand-rolling cluster node context instead of using ClusteredServiceContainer defaults; upgrading Aeron where a previously optional field became required; copying an old sample configuration.","solutions":["Set context.replicationChannel(\"aeron:udp?endpoint=<host>:<port>\") with a unique port per member.","Or call Context.replicationChannel(...) via the configuration property the container reads (aeron.cluster.replication.channel).","Confirm the channel is free/unique per node in multi-node clusters to avoid port conflicts."],"exampleFix":"// before\nConsensusModule.Context ctx = new ConsensusModule.Context()\n    .archiveContext(archiveCtx); // no replication channel\n// after\nConsensusModule.Context ctx = new ConsensusModule.Context()\n    .archiveContext(archiveCtx)\n    .replicationChannel(\"aeron:udp?endpoint=localhost:8040\");","handlingStrategy":"validation","validationCode":"if (ctx.replicationChannel() == null) {\n    throw new IllegalArgumentException(\"replicationChannel must be configured, e.g. aeron:udp?endpoint=host:port\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set replicationChannel with a unique host:port per member","Keep a canonical node config template including replication channel","Verify required context fields after upgrades"],"tags":["aeron-cluster","configuration","archive","replication"],"backgroundTag":"missing-required-config","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"}