{"record":{"id":"ea3938992a7f2501","repo":"aeron-io/aeron","slug":"unable-to-derive-archive-context-archiveclientcontext","errorCode":null,"errorMessage":"Unable to derive Archive.Context.archiveClientContext.controlResponseChannel as Archive.Context.controlChannel.endpoint=${endpoint} and is not in the <host>:<port> format","messagePattern":"Unable to derive Archive\\.Context\\.archiveClientContext\\.controlResponseChannel as Archive\\.Context\\.controlChannel\\.endpoint=(.+?) and is not in the <host>:<port> format","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/Archive.java","lineNumber":1529,"sourceCode":"                    null != recordChecksum ? recordChecksumBuffer() : dataBuffer());\n            }\n\n            if (null == archiveClientContext)\n            {\n                archiveClientContext = new AeronArchive.Context();\n            }\n\n            if (null == archiveClientContext.controlResponseChannel())\n            {\n                if (controlChannelEnabled)\n                {\n                    final ChannelUri controlChannelUri = ChannelUri.parse(controlChannel);\n                    final String endpoint = controlChannelUri.get(ENDPOINT_PARAM_NAME);\n                    final int separatorIndex;\n\n                    if (null == endpoint || -1 == (separatorIndex = endpoint.lastIndexOf(':')))\n                    {\n                        throw new ConfigurationException(\n                            \"Unable to derive Archive.Context.archiveClientContext.controlResponseChannel as \" +\n                                \"Archive.Context.controlChannel.endpoint=\" + endpoint +\n                                \" and is not in the <host>:<port> format\");\n                    }\n\n                    final String responseEndpoint = endpoint.substring(0, separatorIndex) + \":0\";\n                    final String responseChannel = new ChannelUriStringBuilder()\n                        .media(\"udp\")\n                        .endpoint(responseEndpoint)\n                        .build();\n\n                    archiveClientContext.controlResponseChannel(responseChannel);\n                }\n                else\n                {\n                    throw new ConfigurationException(\n                        \"Archive.Context.archiveClientContext.controlResponseChannel must be set if \" +\n                            \"Archive.Context.controlChannelEnabled is false\"","sourceCodeStart":1511,"sourceCodeEnd":1547,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/Archive.java#L1511-L1547","documentation":"When the archive must derive an internal archive client's control-response channel from the control channel URI, it parses the endpoint and replaces the port with 0. If the control channel has no endpoint parameter or the endpoint lacks a '<host>:<port>' form (no ':' present), Archive throws ConfigurationException because the response channel cannot be derived.","triggerScenarios":"Configuring Archive.Context.controlChannel with a URI lacking an endpoint param (e.g. using an interface name or wildcard-only form) while archiveClientContext.controlResponseChannel is unset, forcing derivation from the control channel.","commonSituations":"Using 'aeron:udp?interface=0.0.0.0:8010' style control channels or accidentally omitting endpoint=; multi-host setups where the control channel was copied from driver config.","solutions":["Ensure the control channel URI includes an explicit endpoint in <host>:<port> format, e.g. 'aeron:udp?endpoint=host:8010'.","Explicitly set archiveClientContext.controlResponseChannel(...) so derivation is unnecessary.","Parse the intended URI with ChannelUri to confirm the endpoint parameter is present before launching."],"exampleFix":"// before\nctx.controlChannel(\"aeron:udp?interface=eth0:8010\");\n// after\nctx.controlChannel(\"aeron:udp?endpoint=192.168.1.10:8010\");","handlingStrategy":"validation","validationCode":"ChannelUri uri = ChannelUri.parse(controlChannel);\nString endpoint = uri.get(\"endpoint\");\nif (endpoint == null || endpoint.lastIndexOf(':') < 0)\n{\n    throw new IllegalArgumentException(\"control channel endpoint must be <host>:<port>\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use endpoint=<host>:<port> form in archive control channel URIs","Set archiveClientContext.controlResponseChannel explicitly to avoid derivation logic"],"tags":["aeron","archive","uri","configuration"],"backgroundTag":"invalid-url-format","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"}