{"record":{"id":"cd49ea2e01bd279d","repo":"aeron-io/aeron","slug":"archive-context-controlchannel-must-be-set","errorCode":null,"errorMessage":"Archive.Context.controlChannel must be set","messagePattern":"Archive\\.Context\\.controlChannel must be set","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/Archive.java","lineNumber":1220,"sourceCode":"            if (catalogFileSyncLevel < fileSyncLevel)\n            {\n                throw new ConfigurationException(\n                    \"catalogFileSyncLevel \" + catalogFileSyncLevel + \" < fileSyncLevel \" + fileSyncLevel);\n            }\n\n            if (fileIoMaxLength < TERM_MIN_LENGTH || !BitUtil.isPowerOfTwo(fileIoMaxLength))\n            {\n                throw new ConfigurationException(\"invalid fileIoMaxLength=\" + fileIoMaxLength);\n            }\n\n            io.aeron.driver.Configuration.validateMtuLength(controlMtuLength);\n            checkTermLength(controlTermBufferLength);\n\n            if (controlChannelEnabled)\n            {\n                if (null == controlChannel)\n                {\n                    throw new ConfigurationException(\"Archive.Context.controlChannel must be set\");\n                }\n\n                if (!controlChannel.startsWith(CommonContext.UDP_CHANNEL))\n                {\n                    throw new ConfigurationException(\n                        \"Archive.Context.controlChannel must be UDP media: uri=\" + controlChannel);\n                }\n            }\n\n            if (!localControlChannel.startsWith(CommonContext.IPC_CHANNEL))\n            {\n                throw new ConfigurationException(\"local control channel must be IPC media: uri=\" + localControlChannel);\n            }\n\n            if (null == replicationChannel)\n            {\n                throw new ConfigurationException(\"Archive.Context.replicationChannel must be set\");\n            }","sourceCodeStart":1202,"sourceCodeEnd":1238,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/Archive.java#L1202-L1238","documentation":"When controlChannelEnabled is true the archive needs a control request channel URI to listen on, but Archive.Context.controlChannel is null. The archive cannot accept client control sessions without it, so conclude() fails fast with this ConfigurationException.","triggerScenarios":"Building Archive.Context with controlChannelEnabled(true) (or default enabled) and never calling controlChannel(...); constructing the context programmatically without the corresponding aeron.archive.control.channel property being present.","commonSituations":"Programmatic Archive.Context setup where the property was assumed to fill in defaults; disabling properties file loading so Configuration defaults that normally derive from system properties are skipped; refactors that remove controlChannel(...) while keeping events/replication wiring.","solutions":["Call ctx.controlChannel(\"aeron:udp?endpoint=localhost:8010\") before concluding the context","Set the system/properties value aeron.archive.control.channel","Call ctx.controlChannelEnabled(false) if the control endpoint is intentionally not used"],"exampleFix":"// before\nArchive.Context ctx = new Archive.Context();\n// after\nArchive.Context ctx = new Archive.Context()\n    .controlChannel(\"aeron:udp?endpoint=localhost:8010\");","handlingStrategy":"try-catch","validationCode":"if (ctx.controlChannelEnabled() && ctx.controlChannel() == null) {\n    throw new IllegalArgumentException(\"controlChannel required when controlChannelEnabled\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    archive.start();\n} catch (ConfigurationException e) {\n    log.error(\"Archive configuration invalid: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Always set controlChannel when constructing Archive.Context programmatically","Keep a single factory method for archive contexts so required fields are not forgotten","Load defaults via Archive.Configuration.apply or a properties file rather than ad-hoc wiring"],"tags":["configuration","aeron-archive","missing-value","udp-channel"],"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-15T23:17:13.987Z"}