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={channel} What it means
When a publication URI specifies an explicit 'control' address but neither an 'endpoint' nor a 'control-mode', the driver cannot tell whether this is dynamic MDC or manual control, so it rejects the channel with this IllegalArgumentException. Specifying control alone is ambiguous and therefore invalid.
Solutions
- Add control-mode=dynamic (or manual) to the URI when control is specified
- Or add endpoint=host:port if a unicast publication with explicit control response was intended
- Remove the control parameter if a plain endpoint-based publication was intended
Example fix
// before
aeron.addPublication("aeron:udp?control=localhost:40456", 1001);
// after
aeron.addPublication("aeron:udp?control=localhost:40456|control-mode=dynamic", 1001); Defensive patterns
Strategy: validation
Validate before calling
if (uriParam(channel, "control", null) != null && uriParam(channel, "endpoint", null) == null
&& uriParam(channel, "control-mode", null) == null) {
throw new IllegalArgumentException("control= requires endpoint= or control-mode=: " + channel);
} Try / catch
try { aeron.addPublication(channel, streamId); } catch (IllegalArgumentException e) { if (e.getMessage().contains("'control' parameter requires")) { log.error("specify control-mode or endpoint for {}", channel); } throw e; } Prevention
- Never emit a bare control= parameter in publication URIs
- Keep control+control-mode as an atomic pair in URI builders
- Review URI refactoring diffs for dropped control-mode params
When it happens
Trigger: addPublication with "aeron:udp?control=localhost:40456" and no endpoint and no control-mode parameter; migrating from an MDC URI by deleting control-mode but keeping control.
Common situations: URI trimming/refactoring removed control-mode=dynamic while control remained; hand-written URIs omitting control-mode assuming it is implied by control.
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
- URI must have explicit control, endpoint, or be manual…
- 'control-mode=dynamic' requires that 'control' parameter is…
- explicit control expected with dynamic control mode:
- Unable to derive…
- URI length ( ) exceeds max supported length ( )…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/da105ce6fa33f26f.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2345
{
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())
{
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))View on GitHub (pinned to 6d60124e15)