aeron-io/aeron · error · InvalidChannelException

destinations may not specify control-mode=response

Error message

destinations may not specify control-mode=response

What it means

A destination URI specifies control-mode=response, which is a property of the owning channel, not of individual destinations. The driver rejects response control mode on destinations with InvalidChannelException.

Solutions

  1. Remove control-mode=response from the destination URI; specify it only on the response subscription channel.
  2. Set control-mode=manual or omit control-mode on ordinary destinations.
  3. For response channels, configure response-correlation-id on the response channel itself, not on MDC destinations.

Example fix

// before
publication.addDestination("aeron:udp?endpoint=h:40456|control-mode=response");
// after
publication.addDestination("aeron:udp?endpoint=h:40456");
Defensive patterns

Strategy: validation

Validate before calling

ChannelUri uri = ChannelUri.parse(destination);
if ("response".equals(uri.get("control-mode"))) throw new IllegalArgumentException("destinations may not use control-mode=response");

Type guard

boolean destinationAllowsControlMode(ChannelUri uri) {
  String mode = uri.get("control-mode");
  return mode == null || "manual".equals(mode) || "dynamic".equals(mode);
}

Try / catch

try { publication.addDestination(destination); }
catch (InvalidChannelException e) { if (e.getMessage().contains("control-mode=response")) { /* remove param from destination */ } else throw e; }

Prevention

When it happens

Trigger: Calling Publication.addDestination() / MultiDestination setup with a destination URI containing "control-mode=response".

Common situations: Misunderstanding how response channels work (control-mode=response belongs on the response subscription's channel); generating destination URIs from a response-channel template.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/d98bd8d9897b389d. Report an issue: GitHub.

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2390

    {
        if (SPY_QUALIFIER.equals(uri.prefix()))
        {
            throw new InvalidChannelException("Aeron spies are invalid as send destinations: channel=" +
                destinationUri);
        }

        for (final String invalidKey : INVALID_DESTINATION_KEYS)
        {
            if (uri.containsKey(invalidKey))
            {
                throw new InvalidChannelException(
                    "destinations must not contain the key: " + invalidKey + " channel=" + destinationUri);
            }
        }

        if (Objects.equals(CONTROL_MODE_RESPONSE, uri.get(MDC_CONTROL_MODE_PARAM_NAME)))
        {
            throw new InvalidChannelException("destinations may not specify " +
                MDC_CONTROL_MODE_PARAM_NAME + "=" + CONTROL_MODE_RESPONSE);
        }
    }

    private static void validateSendDestinationUri(final ChannelUri uri, final String destinationUri)
    {
        final String endpoint = uri.get(ENDPOINT_PARAM_NAME);

        if (null != endpoint && endpoint.endsWith(":0"))
        {
            throw new InvalidChannelException(ENDPOINT_PARAM_NAME + " has port=0 for send destination: channel=" +
                destinationUri);
        }
    }

    @SuppressWarnings({ "unused", "UnnecessaryReturnStatement" })
    private static void validateExperimentalFeatures(final boolean enableExperimentalFeatures, final UdpChannel channel)
    {

View on GitHub (pinned to 6d60124e15)