aeron-io/aeron · error · InvalidChannelException
existing publication has clashing sessionId=
Error message
existing publication has clashing sessionId=${sessionId} for streamId=${streamId} channel=${originalChannel} What it means
Aeron publications are keyed by (sessionId, streamId, canonical channel). When adding a new publication whose generated or requested sessionId already exists in the driver's activeSessionSet, this InvalidChannelException is thrown to prevent two publications colliding on the same stream identity.
Solutions
- Omit session-id from the URI and let the driver pick a unique one
- Choose a different explicit session-id that is not currently in use
- Wait for the previous publication (and its drain/cleanup) to complete before re-adding with the same id
- Coordinate session-id allocation across services sharing the stream
Example fix
// before
aeron.addExclusivePublication("aeron:udp?endpoint=localhost:40456|session-id=12345", 1001);
// after
aeron.addExclusivePublication("aeron:udp?endpoint=localhost:40456", 1001); // driver assigns unique sessionId Defensive patterns
Strategy: validation
Validate before calling
Integer sessionId = uriParamInt(channel, "session-id", null);
if (sessionId != null && activeSessions.contains(sessionId, streamId, canonicalChannel)) {
throw new IllegalArgumentException("session-id " + sessionId + " already active on " + streamId);
} Try / catch
try { aeron.addExclusivePublication(channel, streamId); } catch (InvalidChannelException e) { if (e.getMessage().contains("clashing sessionId")) { /* retry without explicit session-id */ } } Prevention
- Let the driver assign session-ids unless you have a specific routing need
- Allocate explicit session-ids from a coordinated range per producer
- Add retry logic that re-adds without session-id on clash
- Avoid rapid publication churn that can race with cleanup
When it happens
Trigger: Calling addPublication/addExclusivePublication with an explicit session-id that equals an active publication's session-id on the same stream/channel; rare random sessionId collision when the driver assigns one; re-adding a publication while the old one is still draining.
Common situations: Manually pinning session-id=? in URIs for stream routing and reusing the value; rapid reconnect loops recreating publications before cleanup; multiple services using the same fixed session-id on a shared stream.
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
- claim exceeds maxPayloadLength of , length=
- EINVAL
- EINVAL
- failed to write next session id command
- formatMatchError(paramName, existingValue, paramsValue…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/851db82fdd2fa025.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2019
{
final SubscriptionLink subscription = subscriptionLinks.get(i);
if (subscription.registrationId() == registrationId && subscription.channel().equals(channel))
{
subscriptionLink = subscription;
fastUnorderedRemove(subscriptionLinks, i);
break;
}
}
return subscriptionLink;
}
private void checkForSessionClash(
final int sessionId, final int streamId, final String channel, final String originalChannel)
{
if (activeSessionSet.contains(new SessionKey(sessionId, streamId, channel)))
{
throw new InvalidChannelException("existing publication has clashing sessionId=" + sessionId +
" for streamId=" + streamId + " channel=" + originalChannel);
}
}
private <T extends DriverManagedResource> void checkManagedResources(
final ArrayList<T> list, final long nowNs, final long nowMs)
{
for (int lastIndex = list.size() - 1, i = lastIndex; i >= 0; i--)
{
final DriverManagedResource resource = list.get(i);
resource.onTimeEvent(nowNs, nowMs, this);
if (resource.hasReachedEndOfLife())
{
fastUnorderedRemove(list, i, lastIndex--);
tryView on GitHub (pinned to 6d60124e15)