{"record":{"id":"f08d5be1af8d53c2","repo":"aeron-io/aeron","slug":"aeronarchive-context-controlrequestchannel-must-be-set","errorCode":null,"errorMessage":"AeronArchive.Context.controlRequestChannel must be set","messagePattern":"AeronArchive\\.Context\\.controlRequestChannel must be set","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java","lineNumber":3095,"sourceCode":"            catch (final CloneNotSupportedException ex)\n            {\n                throw new RuntimeException(ex);\n            }\n        }\n\n        /**\n         * Conclude configuration by setting up defaults when specifics are not provided.\n         */\n        public void conclude()\n        {\n            if ((boolean)IS_CONCLUDED_VH.getAndSet(this, true))\n            {\n                throw new ConcurrentConcludeException();\n            }\n\n            if (null == controlRequestChannel)\n            {\n                throw new ConfigurationException(\"AeronArchive.Context.controlRequestChannel must be set\");\n            }\n\n            if (null == controlResponseChannel)\n            {\n                throw new ConfigurationException(\"AeronArchive.Context.controlResponseChannel must be set\");\n            }\n\n            if (clientName.length() > Aeron.Configuration.MAX_CLIENT_NAME_LENGTH)\n            {\n                throw new ConfigurationException(\n                    \"AeronArchive.Context.clientName length must be <= \" + Aeron.Configuration.MAX_CLIENT_NAME_LENGTH);\n            }\n\n            if (messageRetryAttempts <= 0)\n            {\n                throw new ConfigurationException(\"AeronArchive.Context.messageRetryAttempts must be > 0, got: \" +\n                    messageRetryAttempts);\n            }","sourceCodeStart":3077,"sourceCodeEnd":3113,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java#L3077-L3113","documentation":"AeronArchive.Context.conclude() validates mandatory configuration before connecting. The controlRequestChannel is the URI of the publication used to send commands to the archive; without it the client cannot be built, so a ConfigurationException is thrown at connect time.","triggerScenarios":"Calling AeronArchive.connect() (or Context.conclude()) with a Context whose controlRequestChannel(String) was never called, typically when constructing the context programmatically instead of via properties/system properties.","commonSituations":"Forgetting io.aeron.archive.client.control.request.channel system property; copying a Context from another client and forgetting to set the request channel; building a minimal context for tests.","solutions":["Set ctx.controlRequestChannel(\"aeron:udp?endpoint=<archive-host>:<control-port>\") before connect().","Or set the system property io.aeron.archive.client.control.request.channel to the archive's control channel URI.","If using defaults from a properties file, ensure the file is loaded and the property key spelled correctly.","Print/verify with ctx.controlRequestChannel() right before connect to confirm it is non-null."],"exampleFix":"// before\nAeronArchive.Context ctx = new AeronArchive.Context();\nctx.controlResponseChannel(\"aeron:udp?endpoint=localhost:8021\");\nAeronArchive archive = AeronArchive.connect(ctx);\n// after\nctx.controlRequestChannel(\"aeron:udp?endpoint=localhost:8010\")\n   .controlResponseChannel(\"aeron:udp?endpoint=localhost:8021\");\nAeronArchive archive = AeronArchive.connect(ctx);","handlingStrategy":"validation","validationCode":"if (ctx.controlRequestChannel() == null) { ctx.controlRequestChannel(\"aeron:udp?endpoint=localhost:8010\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set both controlRequestChannel and controlResponseChannel in a shared context factory.","Rely on io.aeron.archive.client.control.request.channel system property with an assert in startup code.","Wrap context creation in a factory method that enforces required fields.","Fail fast in unit tests with a context-completeness check."],"tags":["aeron","archive","configuration","missing-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-19T12:17:13.211Z"}