aeron-io/aeron · error · IllegalArgumentException
control has port=0 for subscription: channel=
Error message
control has port=0 for subscription: channel={channel} What it means
The Java Aeron driver rejects a subscription whose channel URI specifies an explicit control address with port 0. For subscriptions, the explicit control endpoint must have a concrete (non-zero) port so the driver knows where to receive control/setup traffic. This static validation runs in DriverConductor when a network publication or subscription is being added.
Solutions
- Set an explicit non-zero control-port in the channel URI (e.g. control-mode=manual|control=localhost:40456).
- Remove the explicit control address if you do not need MDC and rely on the default control channel instead.
- For publications-only, leave port 0 (dynamic control port) but never on the subscription side.
- Add a config validation step that parses the URI and checks control-port != 0 before calling addSubscription().
Example fix
// before String uri = "aeron:udp?control=224.0.1.1:0|control-mode=manual"; aeron.addSubscription(uri, 1001); // after String uri = "aeron:udp?interface=0.0.0.0:0|control=224.0.1.1:40456|control-mode=manual"; aeron.addSubscription(uri, 1001);
Defensive patterns
Strategy: validation
Validate before calling
ChannelUri uri = ChannelUri.parse(channel);
String control = uri.get("control");
if (control != null && control.endsWith(":0")) throw new IllegalArgumentException("control must not use port 0 for subscriptions"); Type guard
boolean hasValidControlPort(ChannelUri uri) {
String c = uri.get("control");
return c == null || !c.endsWith(":0");
} Try / catch
try { aeron.addSubscription(uri, streamId); }
catch (IllegalArgumentException e) { if (e.getMessage().contains("port=0 for subscription")) { /* fix URI: set explicit control-port */ } else throw e; } Prevention
- Never use port 0 in an explicit control address on subscriptions
- Centralize channel URI construction in a builder that validates control endpoints
- Distinguish publication URIs (dynamic control port OK) from subscription URIs
When it happens
Trigger: Calling Aeron.addSubscription() (or a destination variant) with a channel URI like "aeron:udp?control=hostname|control-port=0" (an explicit control-mode=manual/manual multicast or MDC control address with port 0).
Common situations: Copy-pasting a publication URI (where port 0 can be legal for an ephemeral control port) into a subscription; templated configs where the control-port placeholder was never filled in; MDC setup where the control endpoint was confused with the data endpoint.
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
- AeronArchive.Context.messageRetryAttempts must be > 0, got:
- applicationSpecificFeedback length must be equal to
- clientLivenessTimeoutNs=
- difference greater than 2^31 - 1: termId=
- filePageSize not a power of 2
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/9bcc0205ffebf81f.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2356
"'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())
{
throw new IllegalArgumentException(MDC_CONTROL_PARAM_NAME + " has port=0 for subscription: channel=" +
udpChannel.originalUriString());
}
}
private static void validateTimestampConfiguration(final UdpChannel udpChannel)
{
if (null != udpChannel.channelUri().get(MEDIA_RCV_TIMESTAMP_OFFSET_PARAM_NAME))
{
throw new InvalidChannelException(
"Media timestamps '" + MEDIA_RCV_TIMESTAMP_OFFSET_PARAM_NAME +
"' are not supported in the Java driver: channel=" + udpChannel.originalUriString());
}
}
private static void validateDestinationUri(final ChannelUri uri, final String destinationUri)
{
if (SPY_QUALIFIER.equals(uri.prefix()))
{View on GitHub (pinned to 6d60124e15)