aeron-io/aeron · error · InvalidChannelException
destinations must not contain the key
Error message
destinations must not contain the key: {invalidKey} channel={destinationUri} What it means
When validating destination URIs (for MDC manual destinations, multi-destination publications, or terminals), the driver rejects URIs containing keys that are meaningless or illegal in a destination context (INVALID_DESTINATION_KEYS, e.g. control-related params reserved for the owning channel). The offending key name is included in the message.
Solutions
- Strip the offending key from the destination URI before adding it.
- Build destinations from minimal URIs (endpoint or control only, e.g. "aeron:udp?endpoint=host:port").
- Validate destination URIs with ChannelUri.parse and reject disallowed keys before calling the API.
Example fix
// before
publication.addDestination("aeron:udp?endpoint=h:40456|control-mode=manual");
// after
publication.addDestination("aeron:udp?endpoint=h:40456"); Defensive patterns
Strategy: validation
Validate before calling
ChannelUri uri = ChannelUri.parse(destination);
for (String bad : new String[]{"control-mode", "session-id"})
if (uri.containsKey(bad)) throw new IllegalArgumentException("destination must not contain key: " + bad); Type guard
boolean isCleanDestination(ChannelUri uri) {
return !uri.containsKey("control-mode"); // plus any other INVALID_DESTINATION_KEYS
} Try / catch
try { publication.addDestination(destination); }
catch (InvalidChannelException e) { if (e.getMessage().startsWith("destinations must not contain the key")) { /* rebuild minimal URI */ } else throw e; } Prevention
- Build destination URIs with only endpoint/control params
- Never pass a full channel URI string as a destination
- Parse and sanitize URIs through one shared helper
When it happens
Trigger: Calling Publication.addDestination()/removeDestination() or addRcvDestination() with a URI containing a forbidden key (e.g. control-mode, session-id, or other keys in INVALID_DESTINATION_KEYS).
Common situations: Reusing a full channel URI as a destination string including control params; template-generated URIs carrying extra parameters; copy-paste of subscription channel into destination list.
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
- difference greater than 2^31 - 1: termId=
- endpoint has port=0 for send destination: channel=
- invalid control mode
- invalid maxResend= , must be > 0 and <=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/88c67a58bb2b35f5.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2383
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()))
{
throw new InvalidChannelException("Aeron spies are invalid as send destinations: channel=" +
destinationUri);
}
for (final String invalidKey : INVALID_DESTINATION_KEYS)
{
if (uri.containsKey(invalidKey))
{
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=" +View on GitHub (pinned to 6d60124e15)