{"record":{"id":"f0e5666d015d2bc6","repo":"aeron-io/aeron","slug":"ready-follower-failed-to-notify-leader","errorCode":null,"errorMessage":"ready follower failed to notify leader","messagePattern":"ready follower failed to notify leader","errorType":"exception","errorClass":"TimeoutException","httpStatus":null,"severity":"warning","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/Election.java","lineNumber":1176,"sourceCode":"        else if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))\n        {\n            throw new TimeoutException(\"failed to join live log\", AeronException.Category.WARN);\n        }\n\n        return workCount;\n    }\n\n    private int followerReady(final long nowNs)\n    {\n        if (consensusPublisher.appendPosition(\n            leaderMember.publication(), leadershipTermId, logPosition, thisMember.id(), APPEND_POSITION_FLAG_NONE))\n        {\n            consensusModuleAgent.electionComplete(nowNs);\n            state(CLOSED, nowNs, \"\");\n        }\n        else if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))\n        {\n            throw new TimeoutException(\"ready follower failed to notify leader\", AeronException.Category.WARN);\n        }\n\n        return 1;\n    }\n\n    private void placeVote(final long candidateTermId, final int candidateId, final boolean vote)\n    {\n        final ClusterMember candidate = clusterMemberByIdMap.get(candidateId);\n        if (null != candidate)\n        {\n            consensusPublisher.placeVote(\n                candidate.publication(),\n                candidateTermId,\n                logLeadershipTermId,\n                appendPosition,\n                candidateId,\n                thisMember.id(),\n                vote);","sourceCodeStart":1158,"sourceCodeEnd":1194,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/Election.java#L1158-L1194","documentation":"TimeoutException (WARN) thrown in Election.followerReady: the follower believes it is ready and repeatedly sends its readiness notification to the leader, but the leader never acknowledges (election never completes) within ctx.leaderHeartbeatTimeoutNs. The follower gives up on this election attempt.","triggerScenarios":"In FOLLOWER_READY state each doWork tick sends an election vote/ready message to the leader; if consensusModuleAgent.electionComplete() is never triggered (no leader ack) before timeOfLastStateChangeNs + leaderHeartbeatTimeoutNs, this is thrown.","commonSituations":"Leader crashed right after winning the vote; leader's ingress channel to followers unreachable; leader overloaded and dropping control messages; leaderHeartbeatTimeoutNs too tight; quorum lost so leader cannot complete election.","solutions":["Check the elected leader's logs and health; it likely crashed or lost connectivity","Verify network reachability between follower and leader control channels","Increase ctx.leaderHeartbeatTimeoutNs()","Ensure the cluster maintains quorum (enough members up) so the leader can finish the election"],"exampleFix":"// before\n.leaderHeartbeatTimeoutNs(TimeUnit.SECONDS.toNanos(10))\n// after\n.leaderHeartbeatTimeoutNs(TimeUnit.SECONDS.toNanos(30))","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (TimeoutException e) {\n    // leader never acked readiness; cluster will re-canvas; alert if repeated\n}","preventionTips":["Maintain quorum headroom (spare members)","Monitor leader health and ingress channel","Set leaderHeartbeatTimeoutNs comfortably above election message latency"],"tags":["timeout","election","leader-notification"],"backgroundTag":"request-timeout","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}