aeron-io/aeron · error · IllegalArgumentException

invalid control mode

Error message

invalid control mode: ${controlMode}

What it means

Thrown by ChannelUriStringBuilder.controlMode(String) when the control mode is not one of the allowed values: manual, dynamic, or response. The control mode tells the driver how multicast control messages are managed, so unknown values are rejected at build time.

Solutions

  1. Use ChannelUriStringBuilder.MDC_CONTROL_MODE_MANUAL ("manual").
  2. Use ChannelUriStringBuilder.MDC_CONTROL_MODE_DYNAMIC ("dynamic").
  3. Use CONTROL_MODE_RESPONSE ("response") if response channels are intended; otherwise omit controlMode.

Example fix

// before
builder.controlMode("static");
// after
builder.controlMode(ChannelUriStringBuilder.MDC_CONTROL_MODE_MANUAL);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> OK = Set.of(ChannelUriStringBuilder.MDC_CONTROL_MODE_MANUAL, ChannelUriStringBuilder.MDC_CONTROL_MODE_DYNAMIC, ChannelUriStringBuilder.CONTROL_MODE_RESPONSE);
if (mode != null && !OK.contains(mode)) { throw new IllegalArgumentException("invalid control mode: " + mode); }

Type guard

boolean isValidControlMode(String m) { return m == null || ChannelUriStringBuilder.MDC_CONTROL_MODE_MANUAL.equals(m) || ChannelUriStringBuilder.MDC_CONTROL_MODE_DYNAMIC.equals(m) || ChannelUriStringBuilder.CONTROL_MODE_RESPONSE.equals(m); }

Try / catch

try { builder.controlMode(m); } catch (IllegalArgumentException e) { builder.controlMode(ChannelUriStringBuilder.MDC_CONTROL_MODE_MANUAL); }

Prevention

When it happens

Trigger: builder.controlMode("static"), builder.controlMode("manual-dynamic"), or a config string that isn't exactly MDC_CONTROL_MODE_MANUAL / MDC_CONTROL_MODE_DYNAMIC / CONTROL_MODE_RESPONSE.

Common situations: Guessing mode names ("auto", "static"); case mismatch ("MANUAL"); upgrading from older Aeron versions where only manual/dynamic existed and using a stale constant.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/ChannelUriStringBuilder.java:460

     * Set the control mode for multi-destination-cast. Set to "manual" for allowing control from the publication API.
     *
     * @param controlMode for taking control of MDC.
     * @return this for a fluent API.
     * @see Publication#addDestination(String)
     * @see Publication#removeDestination(String)
     * @see CommonContext#MDC_CONTROL_MODE_PARAM_NAME
     * @see CommonContext#MDC_CONTROL_MODE_MANUAL
     * @see CommonContext#MDC_CONTROL_MODE_DYNAMIC
     * @see CommonContext#CONTROL_MODE_RESPONSE
     */
    public ChannelUriStringBuilder controlMode(final String controlMode)
    {
        if (null != controlMode &&
            !controlMode.equals(MDC_CONTROL_MODE_MANUAL) &&
            !controlMode.equals(MDC_CONTROL_MODE_DYNAMIC) &&
            !controlMode.equals(CONTROL_MODE_RESPONSE))
        {
            throw new IllegalArgumentException("invalid control mode: " + controlMode);
        }

        this.controlMode = controlMode;
        return this;
    }

    /**
     * Set the control mode to be what is in the {@link ChannelUri} which may be null.
     *
     * @param channelUri to read the value from.
     * @return this for a fluent API.
     * @see CommonContext#MDC_CONTROL_MODE_PARAM_NAME
     */
    public ChannelUriStringBuilder controlMode(final ChannelUri channelUri)
    {
        return controlMode(channelUri.get(MDC_CONTROL_MODE_PARAM_NAME));
    }

View on GitHub (pinned to 6d60124e15)