aeron-io/aeron · warning · TimeoutException

failed to join live log

Error message

failed to join live log

What it means

TimeoutException (WARN) thrown when a follower never joins the live log at all: before a subscription was even created or any branch of the live-log state made progress, ctx.leaderHeartbeatTimeoutNs elapsed since the last state change. It is the outer timeout guarding the follower live-log join path.

Solutions

  1. Check whether the elected leader is alive; the cluster should re-canvas after this timeout
  2. Verify inter-member connectivity on the log channels
  3. Increase ctx.leaderHeartbeatTimeoutNs() in slow environments
  4. Restart the member/driver to re-enter the election cleanly
Defensive patterns

Strategy: retry

Try / catch

catch (TimeoutException e) {
    // no live log joined before deadline; leader probably gone; election re-canvas handles retry
}

Prevention

When it happens

Trigger: In followerLiveLog (early branch, e.g. subscription not yet added): if neither the new leadership term/appender arrives nor any progress happens within timeOfLastStateChangeNs + leaderHeartbeatTimeoutNs, this is thrown.

Common situations: Elected leader died before starting the live log; severe network partition; leaderHeartbeatTimeoutNs too small; follower's driver stalled so the new-leadership-term message is never processed.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/f0e160fcffb814c4. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/Election.java:1160

            if (consensusModuleAgent.tryJoinLogAsFollower(image, isLeaderStartup, nowNs))
            {
                updateRecordingLog(nowNs);
                state(FOLLOWER_READY, nowNs, "");
                workCount++;
            }
            else if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))
            {
                throw new TimeoutException("failed to join live log as follower", AeronException.Category.WARN);
            }
        }
        else if (ChannelEndpointStatus.ERRORED == logSubscription.channelStatus())
        {
            final String message = "failed to add live log as follower - " + logSubscription.channel();
            throw new ClusterException(message, AeronException.Category.WARN);
        }
        else if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))
        {
            throw new TimeoutException("failed to join live log", AeronException.Category.WARN);
        }

        return workCount;
    }

    private int followerReady(final long nowNs)
    {
        if (consensusPublisher.appendPosition(
            leaderMember.publication(), leadershipTermId, logPosition, thisMember.id(), APPEND_POSITION_FLAG_NONE))
        {
            consensusModuleAgent.electionComplete(nowNs);
            state(CLOSED, nowNs, "");
        }
        else if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))
        {
            throw new TimeoutException("ready follower failed to notify leader", AeronException.Category.WARN);
        }

View on GitHub (pinned to 6d60124e15)