aeron-io/aeron · error · IllegalArgumentException

URIs for UDP must specify an endpoint, control, tags, or…

Error message

URIs for UDP must specify an endpoint, control, tags, or control-mode=manual/response: 

What it means

UdpChannel.parse throws IllegalArgumentException when a UDP channel URI has no distinguishing characteristic — no endpoint, no control address, and no tags — and the control mode is neither manual nor response. Such a URI gives the driver nothing to bind or connect to, so it is rejected at parse time.

Solutions

  1. Add an endpoint to the URI, e.g. aeron:udp?endpoint=127.0.0.1:40456
  2. For MDC, add control-mode=manual (destinations added at runtime) or an explicit control address/tags
  3. For response channels use control-mode=response; verify parameter spelling (endpoint, control, tags) since unknown params are ignored

Example fix

// before
"aeron:udp"
// after
"aeron:udp?endpoint=127.0.0.1:40456" // or "aeron:udp?control-mode=manual"
Defensive patterns

Strategy: validation

Validate before calling

boolean hasEndpoint = nonEmpty(params.get("endpoint"));
boolean hasControl = nonEmpty(params.get("control"));
boolean hasTags = nonEmpty(params.get("tags"));
String mode = params.get("control-mode");
boolean manualOrResponse = "manual".equals(mode) || "response".equals(mode);
if (!(hasEndpoint || hasControl || hasTags || manualOrResponse)) {
    throw new IllegalArgumentException("UDP channel needs endpoint, control, tags, or control-mode=manual/response");
}

Try / catch

try {
    UdpChannel.parse(uri, true, NameResolver.NULL_NAME_RESOLVER);
} catch (IllegalArgumentException e) {
    // supply an endpoint or a valid control-mode before retrying
}

Prevention

When it happens

Trigger: Passing URIs like aeron:udp or aeron:udp?someOtherParam=x (without endpoint=, control=, tags=, or control-mode=manual/response) to Aeron.addPublication/addSubscription or publication/subscription images.

Common situations: Building URIs programmatically where all endpoint parameters end up empty; typos in parameter names (endpooint=); copy of the response/manual mode usage where control-mode was removed; incomplete MDC configuration.

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/5a19ed12af58757f. Report an issue: GitHub.

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/media/UdpChannel.java:175

            final boolean requiresAdditionalSuffix = !isDestination &&
                (null == endpointAddress && null == controlAddress ||
                (null != endpointAddress && endpointAddress.getPort() == 0) ||
                (null != controlAddress && controlAddress.getPort() == 0));

            final boolean hasNoDistinguishingCharacteristic =
                null == endpointAddress && null == controlAddress && null == tagIdStr;

            if (ControlMode.DYNAMIC == controlMode && null == controlAddress)
            {
                throw new IllegalArgumentException(
                    "explicit control expected with dynamic control mode: " + channelUriString);
            }

            if (hasNoDistinguishingCharacteristic && ControlMode.MANUAL != controlMode &&
                ControlMode.RESPONSE != controlMode)
            {
                throw new IllegalArgumentException(
                    "URIs for UDP must specify an endpoint, control, tags, or control-mode=manual/response: " +
                    channelUriString);
            }

            if (null != endpointAddress && endpointAddress.isUnresolved())
            {
                throw new UnknownHostException("could not resolve endpoint address: " + endpointAddress);
            }

            if (null != controlAddress && controlAddress.isUnresolved())
            {
                throw new UnknownHostException("could not resolve control address: " + controlAddress);
            }

            boolean hasExplicitEndpoint = true;
            if (null == endpointAddress)
            {
                hasExplicitEndpoint = false;

View on GitHub (pinned to 6d60124e15)