aeron-io/aeron · critical · ClusterException
logSessionId was null, should always have a value
Error message
logSessionId was null, should always have a value
What it means
ConsensusPublisher.newLeadershipTerm refuses to send a NewLeadershipTerm message when logSessionId is NULL_SESSION_ID. Every leadership term must have a concrete log session id so followers can attach to the leader's log; null here means internal state was not initialized.
Solutions
- Ensure a valid snapshot/log exists so the leader can establish a real logSessionId before elections complete
- Restore the cluster mark file and snapshot together from the same backup
- Upgrade Aeron — some early versions had election edge cases leaving logSessionId null
- Report/reproduce with Aeron maintainers if it recurs on current versions; this indicates internal state corruption
Example fix
// before: starting election with a wiped mark file (no log session) ClusterException: logSessionId was null, should always have a value // after: restore mark file + snapshot from backup so the term has a valid logSessionId, or bootstrap the cluster cleanly (fresh cluster dir)
Defensive patterns
Strategy: try-catch
Validate before calling
// Before driving an election, verify a real log session exists
if (clusterMarkFile.logSessionId() == CommonContext.NULL_SESSION_ID) {
// restore mark file + snapshot from consistent backup or bootstrap fresh
} Try / catch
try {
election.start();
} catch (ClusterException e) {
if (e.getMessage().contains("logSessionId was null")) {
throw new IllegalStateException("Cluster state not initialized — restore mark file/snapshot from the same backup", e);
}
throw e;
} Prevention
- Back up mark file and snapshot together, always restore together
- Never zero out the cluster mark file manually
- Bootstrap new clusters cleanly rather than editing state files
When it happens
Trigger: An election path calls newLeadershipTerm before the leader has assigned/learned a valid logSessionId (e.g. leadership term initialized without a log session), so the NULL sentinel is passed through.
Common situations: Cluster recovering from an election with a stale/zeroed mark file; bug-level states after failed log replication where the session id was never established; mis-restored cluster mark files.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- unexpected image close during catchup: position=
- election in progress
- potential new election in progress
- invalid newLeadershipTerm - this.appendPosition=
- new leader detected due to commit position - memberId=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/076562ea331284ca.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusPublisher.java:196
final long leadershipTermId,
final long termBaseLogPosition,
final long logPosition,
final long commitPosition,
final long leaderRecordingId,
final long timestamp,
final int leaderMemberId,
final int logSessionId,
final int appVersion,
final boolean isStartup)
{
if (null == publication)
{
return;
}
if (CommonContext.NULL_SESSION_ID == logSessionId)
{
throw new ClusterException("logSessionId was null, should always have a value");
}
final int length = MessageHeaderEncoder.ENCODED_LENGTH + NewLeadershipTermEncoder.BLOCK_LENGTH;
int attempts = SEND_ATTEMPTS;
do
{
final long position = publication.tryClaim(length, bufferClaim);
if (position > 0)
{
newLeadershipTermEncoder
.wrapAndApplyHeader(bufferClaim.buffer(), bufferClaim.offset(), messageHeaderEncoder)
.logLeadershipTermId(logLeadershipTermId)
.nextLeadershipTermId(nextLeadershipTermId)
.nextTermBaseLogPosition(nextTermBaseLogPosition)
.nextLogPosition(nextLogPosition)
.leadershipTermId(leadershipTermId)
.termBaseLogPosition(termBaseLogPosition)View on GitHub (pinned to 6d60124e15)