aeron-io/aeron · error · ClusterException
Live log replay failed
Error message
Live log replay failed: ${poller.code()} What it means
During live log replay the agent polls archive control responses via a ControlResponsePoller. Allowed outcomes advance the state; an ERROR delegates to a detailed exception, and any other unexpected response code makes the agent throw ClusterException 'Live log replay failed: <code>'.
Solutions
- Check archive logs for the control interaction that produced the unexpected code.
- Align the archive client version with the archive server (control protocol change).
- Retry the backup; if persistent, inspect poller.code() against ControlResponseCode and fix archive configuration.
Defensive patterns
Strategy: retry
Validate before calling
// pre-check archive reachable and recording present before backup
archiveClient.listRecordings(0, 10, (c, i) -> {}, (c, i) -> {}); Try / catch
try { ClusterBackup.launch(ctx); } catch (ClusterException e) { if (e.getMessage().startsWith("Live log replay failed")) { scheduleRetryWithBackoff(); } } Prevention
- Keep archive and cluster on matching versions
- Ensure stable, dedicated control channels for the backup
When it happens
Trigger: The archive control poller returns a response code the replay state machine does not expect (not OK, ERROR, or the replay-session code) while awaiting live log replay for the backup.
Common situations: Archive returning protocol responses from a mismatched archive version; unexpected control channel traffic; archive misconfiguration serving the wrong recording.
Related errors
- failed to send bounded replay request
- failed to send replay request
- failed to send stop all replays request
- failed to send stop replay request
- Live log replay failed
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/496dc9d7f1699e3a.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterBackupAgent.java:869
}
}
else if (NULL_VALUE == liveLogReplaySessionId)
{
final ControlResponsePoller poller = clusterArchive.controlResponsePoller();
if (0 != poller.poll() && poller.isPollComplete() &&
poller.controlSessionId() == clusterArchive.controlSessionId() &&
poller.correlationId() == correlationId)
{
switch (poller.code())
{
case OK ->
{
liveLogReplaySessionId = poller.relevantId();
timeOfLastProgressMs = nowMs;
workCount++;
}
case ERROR -> throwReplayFailedException(poller);
default -> throw new ClusterException("Live log replay failed: " + poller.code());
}
}
}
else if (NULL_COUNTER_ID == liveLogRecordingCounterId)
{
final CountersReader countersReader = aeron.countersReader();
liveLogRecordingCounterId = RecordingPos.findCounterIdBySession(
countersReader, (int)liveLogReplaySessionId, backupArchive.archiveId());
if (NULL_COUNTER_ID != liveLogRecordingCounterId)
{
liveLogPositionCounter.setRelease(countersReader.getCounterValue(liveLogRecordingCounterId));
liveLogRecordingId = RecordingPos.getRecordingId(countersReader, liveLogRecordingCounterId);
timeOfLastBackupQueryMs = nowMs;
timeOfLastProgressMs = nowMs;
state(UPDATE_RECORDING_LOG, nowMs);
workCount++;
}View on GitHub (pinned to 6d60124e15)