{"record":{"id":"95ab3d1a0ceeed6b","repo":"aeron-io/aeron","slug":"new-leader-detected-due-to-commit-position-memberid-memberid","errorCode":null,"errorMessage":"new leader detected due to commit position - memberId=${memberId} this.leadershipTermId=${leadershipTermId} this.leaderMemberId=${leaderMemberId} this.logPosition=${logPosition} newLeadershipTermId=${newLeadershipTermId} newLeaderMemberId=${newLeaderMemberId} newCommitPosition=${newCommitPosition})","messagePattern":"new leader detected due to commit position - memberId=(.+?) this\\.leadershipTermId=(.+?) this\\.leaderMemberId=(.+?) this\\.logPosition=(.+?) newLeadershipTermId=(.+?) newLeaderMemberId=(.+?) newCommitPosition=(.+?)\\)","errorType":"exception","errorClass":"ClusterEvent","httpStatus":null,"severity":"critical","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/Election.java","lineNumber":578,"sourceCode":"        if (INIT == state)\n        {\n            return;\n        }\n\n        // we do not check `leadershipTermId == this.leadershipTermId` here, because prior to fixes the leader was\n        // sending wrong `leadershipTermId` value in the `CommitPosition` message (i.e. not matching the one sent\n        // by the `NewLeadershipTerm` message).\n        if (null != leaderMember && leaderMember.id() == leaderMemberId)\n        {\n            notifiedCommitPosition = max(notifiedCommitPosition, logPosition);\n            if (FOLLOWER_LOG_REPLICATION == state)\n            {\n                replicationDeadlineNs = nowNs(ctx) + ctx.leaderHeartbeatTimeoutNs();\n            }\n        }\n        else if (leadershipTermId > this.leadershipTermId && LEADER_READY == state)\n        {\n            throw new ClusterEvent(\"new leader detected due to commit position - \" +\n                \" memberId=\" + thisMemberId() +\n                \" this.leadershipTermId=\" + this.leadershipTermId +\n                \" this.leaderMemberId=\" + (null != leaderMember ? leaderMember.id() : NULL_VALUE) +\n                \" this.logPosition=\" + this.logPosition +\n                \" newLeadershipTermId=\" + leadershipTermId +\n                \" newLeaderMemberId=\" + leaderMemberId +\n                \" newCommitPosition=\" + logPosition +\n                \")\");\n        }\n    }\n\n    void onReplayNewLeadershipTermEvent(\n        final long leadershipTermId,\n        final long logPosition,\n        final long timestamp,\n        final long termBaseLogPosition)\n    {\n        if (INIT == state)","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/Election.java#L560-L596","documentation":"In onCommitPosition, a member in LEADER_READY state receives a commit position for a leadershipTermId greater than its own — proof that another member is already leading a newer term. The member believed it was leader but has been superseded, so it throws ClusterEvent to abort the stale leadership.","triggerScenarios":"A member won an election and entered LEADER_READY, then received a commit position from a different leader with a higher leadershipTermId — two members briefly believed they were leader (expired votes, slow heartbeats) or a higher-term leader emerged while this node's election completion was delayed.","commonSituations":"Network partitions resolved with two competing leaders; heartbeat timeouts too short causing spurious elections; node suspension (GC/VM pause) causing it to miss its win and lose to a new term; clock skew across members.","solutions":["Increase leaderHeartbeatTimeoutNs / election timeouts to tolerate pauses and slow networks","Check for GC pauses or host suspensions on the affected node","Ensure NTP-synchronized clocks across members","Restart the member to rejoin cleanly under the newer leader; upgrade Aeron for improved election dedup logic"],"exampleFix":"// before: brief GC pause causes competing leadership\nClusterEvent: new leader detected due to commit position - memberId=1 this.leadershipTermId=5 ...\n// after\nctx.leaderHeartbeatTimeoutNs(TimeUnit.SECONDS.toNanos(15)); // longer heartbeat tolerance\nelectionTimeoutNs similarly increased","handlingStrategy":"retry","validationCode":"// Tune timeouts up-front so paused nodes don't spuriously lose/claim leadership\nlong hbTimeout = TimeUnit.SECONDS.toNanos(15); // > worst-case GC/host pause","typeGuard":null,"tryCatchPattern":"try {\n    cluster.start();\n} catch (ClusterEvent e) {\n    if (e.getMessage().startsWith(\"new leader detected due to commit position\")) {\n        // rejoin under the newer leader: restart the member\n        restartAndRejoin();\n    } else { throw e; }\n}","preventionTips":["Set leaderHeartbeatTimeoutNs generously above max pause times","Sync clocks via NTP across all members","Investigate GC/host pauses on nodes reporting this event"],"tags":["aeron","cluster","election","leader-conflict"],"backgroundTag":"invalid-state-transition","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}