aeron-io/aeron · error · ClusterException
failed to add live log as follower
Error message
failed to add live log as follower - ${channel} What it means
ClusterException (WARN) thrown when the media driver reports the follower's live log subscription channel as ERRORED while waiting to join the leader's live log. The live log cannot be added, so this member cannot follow the newly elected leader.
Solutions
- Read the media driver error logs for the exact channel failure cause
- Correct the log/logical channel configuration (endpoints, interface, TTL for multicast)
- Ensure ports are available and not firewalled between members
- Restart the driver/node once the channel config is fixed
Example fix
// before
.logChannel("aeron:udp?endpoint=224.20.30.39:20001") // multicast unreachable
// after
.logChannel("aeron:udp?control-mode=manual|group=true&interface=eth0") // fix interface/TTL per driver error Defensive patterns
Strategy: validation
Validate before calling
// validate live log channel config before cluster start
ChannelUri logUri = ChannelUri.parse(ctx.logChannel());
if ("udp".equals(logUri.get("media")) && !resolvable(logUri.get("endpoint"))) {
throw new IllegalArgumentException("live log endpoint unresolvable");
} Try / catch
catch (ClusterException e) {
if (e.getMessage().startsWith("failed to add live log")) {
// inspect driver error log; fix channel URI/interface; restart
}
} Prevention
- Validate log channel URIs at startup
- Avoid port conflicts across members
- Verify network interfaces named in channel URIs exist
When it happens
Trigger: During FOLLOWER_LIVE_LOG_AWAIT, logSubscription.channelStatus() becomes ChannelEndpointStatus.ERRORED, e.g. the driver failed to resolve/bind or the channel URI is invalid for the live log stream.
Common situations: Bad log channel endpoints in cluster member config, port conflicts, unreachable multicast groups, driver-side network errors after leader change rewired channels.
Related errors
- failed to add catchup log as follower
- Archive.Context.controlChannel must be set
- Archive.Context.controlChannel must be UDP media: uri=
- archive is not connected
- channel error -
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/4b52ff2ce307c7be.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/Election.java:1156
final Image image = logSubscription.imageBySessionId(logSessionId);
if (null != image)
{
verifyLogJoinPosition("followerLogAwait", image.joinPosition());
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()))View on GitHub (pinned to 6d60124e15)