aeron-io/aeron · error · InvalidChannelException
endpoint has port=0 for send destination: channel=
Error message
endpoint has port=0 for send destination: channel={destinationUri} What it means
A send destination URI includes an endpoint parameter ending in ":0", i.e. an explicitly requested port 0. Port 0 (ephemeral) is not meaningful for a send destination because the driver must send data to a concrete remote port; the driver throws InvalidChannelException.
Solutions
- Set a concrete remote port in the destination endpoint (e.g. endpoint=host:40456).
- If a dynamic local port is needed, use the interface/endpoints parameter for binding, not the send endpoint.
- Add pre-call validation: reject destination URIs whose endpoint ends with ":0".
Example fix
// before
publication.addDestination("aeron:udp?endpoint=host:0");
// after
publication.addDestination("aeron:udp?endpoint=host:40456"); Defensive patterns
Strategy: validation
Validate before calling
ChannelUri uri = ChannelUri.parse(destination);
String endpoint = uri.get("endpoint");
if (endpoint != null && endpoint.endsWith(":0")) throw new IllegalArgumentException("send destination endpoint needs a concrete port"); Type guard
boolean hasConcreteSendPort(ChannelUri uri) {
String ep = uri.get("endpoint");
return ep == null || !ep.endsWith(":0");
} Try / catch
try { publication.addDestination(destination); }
catch (InvalidChannelException e) { if (e.getMessage().contains("has port=0 for send destination")) { /* set a real port */ } else throw e; } Prevention
- Reject ":0" endpoints in destination template rendering
- Differentiate bind endpoints (port 0 allowed) from send endpoints (not allowed)
- Store remote ports in config with explicit defaults
When it happens
Trigger: Calling Publication.addDestination() or creating an MDC send channel with a destination like "aeron:udp?endpoint=host:0".
Common situations: Unfilled port placeholders in generated configs; copying a bind-endpoint (where port 0 can request an ephemeral local port) into an endpoint used as a send target; typos like ":O" avoided but ":0" kept.
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
- destinations may not specify control-mode=response
- destinations must not contain the key
- invalid port
- Aeron spies are invalid as send destinations: channel=
- AeronArchive.Context.messageRetryAttempts must be > 0, got:
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/5b2b349cc219c40d.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2401
throw new InvalidChannelException(
"destinations must not contain the key: " + invalidKey + " channel=" + destinationUri);
}
}
if (Objects.equals(CONTROL_MODE_RESPONSE, uri.get(MDC_CONTROL_MODE_PARAM_NAME)))
{
throw new InvalidChannelException("destinations may not specify " +
MDC_CONTROL_MODE_PARAM_NAME + "=" + CONTROL_MODE_RESPONSE);
}
}
private static void validateSendDestinationUri(final ChannelUri uri, final String destinationUri)
{
final String endpoint = uri.get(ENDPOINT_PARAM_NAME);
if (null != endpoint && endpoint.endsWith(":0"))
{
throw new InvalidChannelException(ENDPOINT_PARAM_NAME + " has port=0 for send destination: channel=" +
destinationUri);
}
}
@SuppressWarnings({ "unused", "UnnecessaryReturnStatement" })
private static void validateExperimentalFeatures(final boolean enableExperimentalFeatures, final UdpChannel channel)
{
if (enableExperimentalFeatures)
{
return;
}
/*
* Put experimental feature validation here.
*/
}
static FeedbackDelayGenerator resolveDelayGenerator(View on GitHub (pinned to 6d60124e15)