aeron-io/aeron · error · IllegalArgumentException
either 'endpoint' or 'control' must be specified for UDP.
Error message
either 'endpoint' or 'control' must be specified for UDP.
What it means
For UDP channels, validate() requires a routing destination: either a unicast/multicast endpoint or a control (multicast) endpoint must be set. A UDP media with both endpoint and controlEndpoint null has nowhere to send, so IllegalArgumentException is thrown.
Solutions
- Add .endpoint("host:port") (or .control(multicastAddress:port)) to the builder for UDP channels
- Verify the config actually contains the endpoint or control value and that the key name matches
- If the channel is genuinely local-only, use media "ipc" instead of udp
Example fix
// before
new ChannelUriStringBuilder().media(CommonContext.UDP_MEDIA).validate();
// after
new ChannelUriStringBuilder()
.media(CommonContext.UDP_MEDIA)
.endpoint("localhost:40456")
.validate(); Defensive patterns
Strategy: validation
Validate before calling
static void requireUdpDestination(String media, String endpoint, String control) {
if ("udp".equals(media) && endpoint == null && control == null) {
throw new IllegalArgumentException("udp channel requires 'endpoint' or 'control'");
}
} Type guard
static boolean hasUdpDestination(ChannelUriStringBuilder b) {
try { b.validate(); return true; } catch (IllegalArgumentException e) { return false; }
} Try / catch
try {
String uri = builder.validate().build();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("either 'endpoint' or 'control'")) {
throw new IllegalArgumentException("UDP channel config must set endpoint or control", e);
}
throw e;
} Prevention
- For every udp channel, set endpoint (unicast/multicast) or control (MDC)
- If the channel is local-only, switch to media "ipc" instead of udp
- Keep endpoint/control config keys in one schema and validate before building URIs
When it happens
Trigger: Builder with media("udp") but neither .endpoint(...) nor .control(...) called, then validate()/build(). IPC channels are exempt from this check.
Common situations: Reusing a builder configured for IPC with UDP media; config file that specifies transport=udp but omits endpoint/control keys; code paths that assume a default endpoint exists.
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
- media type is mandatory
- either all or none of the parameters ['initialTermId'…
- segment file length not a power of 2
- segment file length not in valid range
- AeronArchive.Context.messageRetryAttempts must be > 0, got:
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/7ffa085aa2543929.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/ChannelUriStringBuilder.java:221
return this;
}
/**
* Validates that the collection of set parameters are valid together.
*
* @return this for a fluent API.
* @throws IllegalArgumentException if the combination of params is invalid.
*/
public ChannelUriStringBuilder validate()
{
if (null == media)
{
throw new IllegalArgumentException("media type is mandatory");
}
if (CommonContext.UDP_MEDIA.equals(media) && (null == endpoint && null == controlEndpoint))
{
throw new IllegalArgumentException("either 'endpoint' or 'control' must be specified for UDP.");
}
final boolean anyNonNull = null != initialTermId || null != termId || null != termOffset;
final boolean anyNull = null == initialTermId || null == termId || null == termOffset;
if (anyNonNull)
{
if (anyNull)
{
throw new IllegalArgumentException(
"either all or none of the parameters ['initialTermId', 'termId', 'termOffset'] must be provided");
}
if (termId - initialTermId < 0)
{
throw new IllegalArgumentException(
"difference greater than 2^31 - 1: termId=" + termId + " - initialTermId=" + initialTermId);
}
View on GitHub (pinned to 6d60124e15)