{"record":{"id":"6216b3c5c82e9eed","repo":"aeron-io/aeron","slug":"logchannel-must-not-contain-termoffset-param-name","errorCode":null,"errorMessage":"logChannel must not contain: <termOffset param name>","messagePattern":"logChannel must not contain: <termOffset param name>","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java","lineNumber":4622,"sourceCode":"            }\n\n            throw new ClusterException(\"invalid TimerServiceSupplier: \" + timeServiceClassName);\n        }\n\n        private void validateLogChannel()\n        {\n            final ChannelUri logChannelUri = parse(logChannel);\n            if (logChannelUri.containsKey(INITIAL_TERM_ID_PARAM_NAME))\n            {\n                throw new ConfigurationException(\"logChannel must not contain: \" + INITIAL_TERM_ID_PARAM_NAME);\n            }\n            if (logChannelUri.containsKey(TERM_ID_PARAM_NAME))\n            {\n                throw new ConfigurationException(\"logChannel must not contain: \" + TERM_ID_PARAM_NAME);\n            }\n            if (logChannelUri.containsKey(TERM_OFFSET_PARAM_NAME))\n            {\n                throw new ConfigurationException(\"logChannel must not contain: \" + TERM_OFFSET_PARAM_NAME);\n            }\n        }\n\n        /**\n         * {@inheritDoc}\n         */\n        @Override\n        public String toString()\n        {\n            return \"ConsensusModule.Context\" +\n                \"\\n{\" +\n                \"\\n    isConcluded=\" + isConcluded() +\n                \"\\n    ownsAeronClient=\" + ownsAeronClient +\n                \"\\n    aeronDirectoryName='\" + aeronDirectoryName + '\\'' +\n                \"\\n    aeron=\" + aeron +\n                \"\\n    deleteDirOnStart=\" + deleteDirOnStart +\n                \"\\n    clusterDirectoryName='\" + clusterDirectoryName + '\\'' +\n                \"\\n    clusterDir=\" + clusterDir +","sourceCodeStart":4604,"sourceCodeEnd":4640,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java#L4604-L4640","documentation":"Final branch of validateLogChannel(): the logChannel URI must not contain termOffset, as cluster consensus must control the offset within the log term. A ConfigurationException naming the parameter is thrown.","triggerScenarios":"logChannel URI includes termOffset, e.g. 'aeron:udp?endpoint=...|termOffset=0'.","commonSituations":"Channel string reused from a replay/recording publication configuration; attempts to resume a log at a specific offset by pinning termOffset.","solutions":["Remove termOffset from the logChannel URI.","For log recovery, rely on the cluster's replay mechanism rather than pinning channel params.","Restrict the logChannel to transport parameters only."],"exampleFix":"// before\nctx.logChannel(\"aeron:udp?endpoint=localhost:20000|termOffset=0\");\n// after\nctx.logChannel(\"aeron:udp?endpoint=localhost:20000\");","handlingStrategy":"validation","validationCode":"ChannelUri uri = ChannelUri.parse(logChannel);\nif (uri.containsKey(\"termOffset\")) {\n    throw new IllegalArgumentException(\"logChannel must not contain termOffset\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pin termOffset on the cluster log channel","Rely on cluster replay/recovery for offsets","Sanitize channel URIs copied from other Aeron components"],"tags":["aeron-cluster","configuration","channel-uri","log-channel"],"backgroundTag":"invalid-config-value","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}