aeron-io/aeron · error · InvalidChannelException
option conflicts with existing subscription: reliable=
Error message
option conflicts with existing subscription: reliable=${isReliable} existingChannel=${existingChannel} channel=${channel} What it means
Within a single Aeron client, all subscriptions sharing a channel endpoint and streamId must agree on the 'reliable' option. The driver throws this InvalidChannelException when a new addSubscription matches an existing subscription on channel/stream/tag but declares a different reliable value.
Solutions
- Align the reliable parameter across all addSubscription calls for the same channel/streamId
- Remove or close the conflicting existing subscription first
- Use a different streamId or session-id range if different reliability semantics are genuinely needed
- Centralize channel URI construction so all subscribers share one config source
Example fix
// before
aeron.addSubscription("aeron:udp?endpoint=localhost:40456|reliable=false", 1001);
// after (match existing subscription)
aeron.addSubscription("aeron:udp?endpoint=localhost:40456|reliable=true", 1001); Defensive patterns
Strategy: try-catch
Validate before calling
boolean reliable = Boolean.parseBoolean(uriParam(channel, "reliable", "true")); // assert reliable matches the value used by all other subscribers of this channel/streamId
Try / catch
try { aeron.addSubscription(channel, streamId, handler, unavailableHandler); } catch (InvalidChannelException e) { if (e.getMessage().contains("option conflicts")) { log.error("align reliable option with existing subscription: {}", e.getMessage()); } throw e; } Prevention
- Centralize subscription URI templates so reliable= is set in exactly one place
- Document the reliable setting for each shared stream
- Close conflicting subscriptions before re-adding with changed options
- Search the codebase for all addSubscription calls on a stream when changing options
When it happens
Trigger: Calling Aeron.addSubscription with reliable=false (or true) on a URI/streamId where a subscription with the opposite reliable setting already exists and matches the same endpoint, stream, and tag.
Common situations: Two parts of an application independently subscribing to the same channel/stream with divergent reliability config; a shared library component adds subscriptions with its own defaults; copying URIs between services with different ?reliable= values.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- option conflicts with existing subscription: rejoin=
- option conflicts with existing subscription: isResponse=
- option conflicts with existing subscription
- option conflicts with existing subscription
- = does not match existing value of : existingChannel=…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/a19f4d7a282ce8ac.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:1622
}
private void checkForClashingSubscription(
final SubscriptionParams params, final UdpChannel udpChannel, final int streamId)
{
final ReceiveChannelEndpoint channelEndpoint = findExistingReceiveChannelEndpoint(udpChannel);
if (null != channelEndpoint)
{
validateUdpChannelAgainstReceiveChannelEndpoint(params, udpChannel, channelEndpoint);
for (final SubscriptionLink subscription : subscriptionLinks)
{
final boolean matchesTag = !udpChannel.hasTag() || channelEndpoint.matchesTag(udpChannel);
if (matchesTag && subscription.matches(channelEndpoint, streamId, params))
{
if (params.isReliable != subscription.isReliable())
{
throw new InvalidChannelException(
"option conflicts with existing subscription: reliable=" + params.isReliable +
" existingChannel=" + subscription.channel() + " channel=" +
udpChannel.originalUriString());
}
if (params.isRejoin != subscription.isRejoin())
{
throw new InvalidChannelException(
"option conflicts with existing subscription: rejoin=" + params.isRejoin +
" existingChannel=" + subscription.channel() + " channel=" +
udpChannel.originalUriString());
}
if (params.isResponse != subscription.isResponse())
{
throw new InvalidChannelException(
"option conflicts with existing subscription: isResponse=" + params.isResponse +
" existingChannel=" + subscription.channel() + " channel=" +View on GitHub (pinned to 6d60124e15)