aeron-io/aeron · critical · ClusterException
clashing open clusterSessionId=
Error message
clashing open clusterSessionId=<clusterSessionId> leadershipTermId=<leadershipTermId> logPosition=<logPosition>
What it means
When the log notifies the service agent of a session open (onSessionOpen path), the agent checks sessionByIdMap for an existing session with the same clusterSessionId. A duplicate indicates corrupted or replayed log state and throws ClusterException, since two live sessions cannot share one id.
Solutions
- Verify the snapshot/log pairing: ensure the snapshot was taken at or before the log position being replayed, with no overlap.
- Point the service at the correct cluster directory/log; a mismatched or foreign log can contain ids already in memory.
- If state files are corrupted, restore from a known-good snapshot and log; report persistent duplication as a bug to the Aeron project.
Example fix
// before # start service with snapshot S and log L where L overlaps S // after # ensure log position >= snapshot position ctx.clusterDir(correctDir); // snapshot + log from the same cluster instance
Defensive patterns
Strategy: validation
Validate before calling
// java: confirm snapshot/log consistency before starting the service
long snapshotPos = readSnapshotLogPosition(snapshotFile);
long replayFrom = readRecoveryPlanLogPosition();
if (replayFrom < snapshotPos) {
throw new IllegalStateException("log position overlaps snapshot; inconsistent recovery plan");
} Try / catch
try {
serviceContainer.start();
} catch (ClusterException e) {
if (e.getMessage().contains("clashing open clusterSessionId")) {
// stop, restore a consistent snapshot+log pair, then restart
}
throw e;
} Prevention
- Always restore snapshots and logs from the same cluster instance and recovery plan.
- Take snapshots only at committed positions and never mix backup files from different clusters.
- Monitor for duplicated session-open events after crash recovery.
When it happens
Trigger: Processing a session-open log event for a clusterSessionId already present in sessionByIdMap — e.g. replaying a log position already applied, a duplicated log event, or internal bookkeeping failure between snapshot and replay.
Common situations: Restoring from an inconsistent snapshot while replaying a log; running a service against the wrong/overlapping log; a bug in log recovery causing double application of the same open event.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- unknown clusterSessionId
- className is empty
- ClusterMarkFile headerLength=
- ControlSession.RESPONSE_NOT_CONNECTED_MSG + ": " + session
- Counter id is not allocated:
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/4904a98848ee0cd9.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/service/ClusteredServiceAgent.java:521
clusterTime = timestamp;
service.onTimerEvent(correlationId, timestamp);
}
void onSessionOpen(
final long leadershipTermId,
final long logPosition,
final long clusterSessionId,
final long timestamp,
final int responseStreamId,
final String responseChannel,
final byte[] encodedPrincipal)
{
this.logPosition = logPosition;
clusterTime = timestamp;
if (sessionByIdMap.containsKey(clusterSessionId))
{
throw new ClusterException("clashing open clusterSessionId=" + clusterSessionId +
" leadershipTermId=" + leadershipTermId + " logPosition=" + logPosition);
}
final ContainerClientSession session = new ContainerClientSession(
clusterSessionId, responseStreamId, responseChannel, encodedPrincipal, this);
if (Role.LEADER == role && ctx.isRespondingService())
{
session.connect(aeron);
}
addSession(session);
service.onSessionOpen(session, timestamp);
}
void onSessionClose(
final long leadershipTermId,
final long logPosition,View on GitHub (pinned to 6d60124e15)