{"record":{"id":"7782f8b132bf1f88","repo":"aeron-io/aeron","slug":"invalid-channel-does-not-allow-manual-control","errorCode":"INVALID_CHANNEL","errorMessage":"channel does not allow manual control","messagePattern":"channel does not allow manual control","errorType":"error_code","errorClass":"ControlProtocolException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/media/SendChannelEndpoint.java","lineNumber":570,"sourceCode":"        {\n            final long responseCorrelationId = publication.responseCorrelationId();\n            if (Aeron.NULL_VALUE != responseCorrelationId)\n            {\n                conductorProxy.responseSetup(responseCorrelationId, msg.responseSessionId());\n            }\n        }\n    }\n\n    /**\n     * Validate that the channel allows manual control for destinations.\n     * <p>\n     * If not then a {@link ControlProtocolException} will be thrown.\n     */\n    public void validateAllowsManualControl()\n    {\n        if (!(multiSndDestination instanceof ManualSndMultiDestination))\n        {\n            throw new ControlProtocolException(ErrorCode.INVALID_CHANNEL, \"channel does not allow manual control\");\n        }\n    }\n\n    /**\n     * Add a destination for an MDC channel.\n     *\n     * @param channelUri     for the destination to be added.\n     * @param address        of the destination to be added.\n     * @param registrationId of the destination.\n     */\n    public void addDestination(final ChannelUri channelUri, final InetSocketAddress address, final long registrationId)\n    {\n        multiSndDestination.addDestination(channelUri, address, registrationId);\n    }\n\n    /**\n     * Remove a destination from an MDC channel.\n     *","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/media/SendChannelEndpoint.java#L552-L588","documentation":"Aeron throws ControlProtocolException(ErrorCode.INVALID_CHANNEL) when a manual control operation (add/remove destination) is performed on a send channel endpoint whose multiSndDestination is not a ManualSndMultiDestination. Only publication channels created with control-mode=manual allow dynamic destination management.","triggerScenarios":"validateAllowsManualControl is invoked from findExistingManualSendChannelEndpoint when reusing/looking up a send channel for a manual-control request, and the existing endpoint was created from a URI without control-mode=manual.","commonSituations":"Calling Publication.addDestination/removeDestination on a publication created from a normal aeron:udp?endpoint=... URI; an existing publication on the same stream/URI was created without manual mode so the endpoint reuse fails; MDC publishing configured incorrectly.","solutions":["Create the publication channel URI with control-mode=manual, e.g. aeron:udp?control-mode=manual","Ensure all publications on the same channel/stream use consistent control mode so endpoint lookup finds a manual-capable endpoint","Catch ControlProtocolException and inspect getErrorCode() == ErrorCode.INVALID_CHANNEL to detect the misconfiguration"],"exampleFix":"// before\nPublication pub = aeron.addPublication(\"aeron:udp?endpoint=224.0.1.1:40456\", 1001);\npub.addDestination(\"aeron:udp?endpoint=10.0.0.1:40456\"); // throws\n// after\nPublication pub = aeron.addPublication(\"aeron:udp?control-mode=manual\", 1001);\npub.addDestination(\"aeron:udp?endpoint=10.0.0.1:40456\");","handlingStrategy":"try-catch","validationCode":"boolean manual = uri.contains(\"control-mode=manual\");\nif (!manual) throw new IllegalStateException(\"send channel must use control-mode=manual for addDestination\");","typeGuard":null,"tryCatchPattern":"try {\n    publication.addDestination(dstUri);\n} catch (ControlProtocolException e) {\n    if (e.errorCode() == ErrorCode.INVALID_CHANNEL) { /* recreate publication with control-mode=manual */ }\n}","preventionTips":["Create MDC publications with control-mode=manual in the URI","Keep control mode consistent across all publications on the same channel so endpoint reuse succeeds","Guard destination add/remove calls behind a check that the publication was created in manual mode"],"tags":["aeron","mdc","configuration","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-16T04:17:20.429Z"}