aeron-io/aeron · error · IllegalStateException
election in progress
Error message
election in progress
What it means
enterElection starts a new cluster election. The module allows only one election at a time; if enterElection is called while an election object is already active, IllegalStateException is thrown to signal the internal state machine was violated.
Solutions
- Capture full agent logs to see why enterElection was re-entered (reason string is logged)
- Check for network flapping causing repeated end-of-stream signals
- Update Aeron to the latest patch release; several election re-entry races have been fixed
- Restart the node to clear the stuck election state
Example fix
// before: re-entering election without checking state
agent.enterElection(isEos, reason);
// after: guard with election null check
if (null == election)
{
agent.enterElection(isEos, reason);
} Defensive patterns
Strategy: try-catch
Try / catch
catch (IllegalStateException e)
{
if ("election in progress".equals(e.getMessage()))
{
log.warn("election re-entry attempt ignored");
return; // let the active election finish
}
throw e;
} Prevention
- Guard all election entry points with a null election check
- Fix network flapping that generates repeated end-of-stream events
- Keep Aeron updated; election races are patched in maintenance releases
- Serialize election-triggering events through the agent duty cycle only
When it happens
Trigger: Thrown when election != null upon entering enterElection, e.g. an end-of-stream event or failure triggers a second election while the current one is still in progress.
Common situations: Leader and follower connectivity flapping, generating repeated end-of-stream events; a bug or race in election completion logic; concurrent failure events arriving during an active election.
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
- unexpected image close during catchup: position=
- logSessionId was null, should always have a value
- 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/45771af6852b86fb.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModuleAgent.java:3064
}
if (!uncommittedPreviousState.isEmpty())
{
uncommittedPreviousState.pollLong();
final ConsensusModule.State committedState = ConsensusModule.State.get(uncommittedPreviousState.pollLong());
if (ConsensusModule.State.CLOSED != state)
{
state(committedState, "rollback");
}
}
uncommittedPreviousState.clear();
}
private void enterElection(final boolean isLogEndOfStream, final String reason)
{
if (null != election)
{
throw new IllegalStateException("election in progress");
}
role(Cluster.Role.FOLLOWER);
final long leadershipTermId = this.leadershipTermId;
final RecordingLog.Entry termEntry = recordingLog.findTermEntry(leadershipTermId);
final long termBaseLogPosition = null != termEntry ?
termEntry.termBaseLogPosition : recoveryPlan.lastTermBaseLogPosition();
final long appendedPosition = null != appendPosition ?
appendPosition.get() : max(recoveryPlan.appendedLogPosition(), logRecordingStopPosition);
final long commitPosition = this.commitPosition.getPlain();
logNewElection(memberId, leadershipTermId, commitPosition, appendedPosition, reason);
ctx.countedErrorHandler().onError(new ClusterEvent(reason));
election = new Election(
false,
isLogEndOfStream ? leaderMember.id() : NULL_VALUE,View on GitHub (pinned to 6d60124e15)