aeron-io/aeron · error · IllegalArgumentException

'control-mode=dynamic' requires that 'control' parameter is…

Error message

'control-mode=dynamic' requires that 'control' parameter is set, channel=${originalUriString}

What it means

'control-mode=dynamic' multi-destination-cast publications need a concrete 'control' address that receivers subscribe to; without it the driver cannot bind the control endpoint. This IllegalArgumentException is thrown when a publication URI sets control-mode=dynamic but has no explicit control parameter.

Solutions

  1. Add control=host:port to the publication URI alongside control-mode=dynamic
  2. Or use control-mode=manual if destinations are added programmatically instead
  3. Remove control-mode=dynamic if unicast endpoint publication was intended

Example fix

// before
aeron.addPublication("aeron:udp?control-mode=dynamic", 1001);
// after
aeron.addPublication("aeron:udp?control=localhost:40456|control-mode=dynamic", 1001);
Defensive patterns

Strategy: validation

Validate before calling

if ("dynamic".equals(uriParam(channel, "control-mode", null)) && uriParam(channel, "control", null) == null) {
    throw new IllegalArgumentException("control-mode=dynamic requires control= : " + channel);
}

Try / catch

try { aeron.addPublication(channel, streamId); } catch (IllegalArgumentException e) { if (e.getMessage().contains("'control-mode=dynamic' requires")) { log.error("add control= to {}", channel); } throw e; }

Prevention

When it happens

Trigger: addPublication with "aeron:udp?control-mode=dynamic" but no control=host:port; building MDC URIs where the control parameter is dropped by a template; renaming mistakes (ctrl vs control).

Common situations: Misconfigured MDC setup where senders specify dynamic control mode but forget the control address; docs/examples partially copied; env-driven URI assembly losing the control param.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

                    ": existingChannel=" + existingChannel + " channel=" + channel);
        }
    }

    private static void validateEndpointForPublication(final UdpChannel udpChannel)
    {
        if (!udpChannel.isMultiDestination() && udpChannel.hasExplicitEndpoint() &&
            0 == udpChannel.remoteData().getPort())
        {
            throw new IllegalArgumentException(
                ENDPOINT_PARAM_NAME + " has port=0 for publication: channel=" + udpChannel.originalUriString());
        }
    }

    private static void validateControlForPublication(final UdpChannel udpChannel)
    {
        if (udpChannel.isDynamicControlMode() && !udpChannel.hasExplicitControl())
        {
            throw new IllegalArgumentException(
                "'control-mode=dynamic' requires that 'control' parameter is set, channel=" +
                    udpChannel.originalUriString());
        }

        if (udpChannel.hasExplicitControl() && !udpChannel.hasExplicitEndpoint() &&
            ControlMode.NONE == udpChannel.controlMode())
        {
            throw new IllegalArgumentException(
                "'control' parameter requires that either 'endpoint' or 'control-mode' is specified, channel=" +
                    udpChannel.originalUriString());
        }
    }

    private static void validateControlForSubscription(final UdpChannel udpChannel)
    {
        if (udpChannel.hasExplicitControl() &&
            0 == udpChannel.localControl().getPort())
        {

View on GitHub (pinned to 6d60124e15)