aeron-io/aeron · error · TimeoutException
failed to send replay request
Error message
failed to send replay request
What it means
Thrown by ReplicationSession.replay() when the archive proxy repeatedly fails to enqueue the replay request to the source archive's control endpoint, and the action timeout (default aeron.archive.replication.timeout or Archive.Configuration ACTION_TIMEOUT) elapses. archiveProxy.replay() returns false when the underlying publication cannot accept the control message (not connected, no window/credit, or back-pressured), so the state machine retries until the deadline. It signals that the replication could never get its replay request to the source archive.
Solutions
- Verify the source archive is running and reachable: check its control-request channel/port and test connectivity (ping/nc) from the destination host.
- Check source archive logs for a control session rejection or termination around the failure time; fix auth/session issues and re-run the replication.
- Increase Aeron's replication action timeout (aeron.archive.replication.timeout, or the replicationTimeout argument to AeronArchive.replicate) so transient back-pressure can clear.
- Validate the replicationChannel URI (endpoint, control-mode) — ensure the endpoint resolves and wildcard ports can be resolved on both sides.
- Confirm both drivers are up and sender/receiver statuses are active (use Aeronstat / driver status) before retrying.
Example fix
// before: default short timeout on a slow WAN
archive.replicate(srcRecordingId, liveChannel, liveStreamId, dstRecordingId);
// after: explicit replication timeout of 30s
archive.replicate(
srcRecordingId,
dstRecordingId,
liveChannel,
liveStreamId,
replayPosition,
AeronArchive.NULL_LENGTH,
replicationChannel,
replicationChannelStreamId,
TimeUnit.SECONDS.toNanos(30) /* replicationTimeout */); Defensive patterns
Strategy: retry
Validate before calling
// Before starting replication, check source archive reachability
try (AeronArchive archive = AeronArchive.connect(archiveCtx))
{
// throws if the control channel is not usable
archive.listRecording(srcRecordingId, (c, l, d) -> {});
} Try / catch
int attempts = 3;
while (attempts-- > 0)
{
try
{
long replicationId = archive.replicate(srcRecordingId, replicationChannel, replayStreamId);
break;
}
catch (io.aeron.exceptions.TimeoutException e)
{
if (attempts == 0) throw e;
Thread.sleep(1000);
}
} Prevention
- Monitor source archive health (conductor alive, control channel connected) before initiating replication
- Set aeron.archive.replication.timeout appropriately for your WAN latency, not the default
- Keep both Aeron drivers running under supervision (systemd) so a driver restart does not strand in-flight replication
- Alert on archive control publication back-pressure metrics
When it happens
Trigger: archiveProxy.replay(srcRecordingId, ...) returns false on every doWork() cycle for actionTimeoutMs while activeCorrelationId is NULL; typically because the source archive control-response/control-request publication is not connected, the media driver is down, or the UDP link between destination and source archive is down.
Common situations: Source archive process down or restarting; firewall/NAT dropping the control channel; replicationChannel misconfigured (wrong endpoint/port); source archive control session terminated mid-replication; severe network congestion keeping the control publication back-pressured for longer than the replication timeout; actionTimeoutMs set too low for a slow/high-latency WAN.
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
- failed to fetch remote recording descriptor
- failed get acknowledgement of replay request to: " +…
- failed get replay image for sessionId=" +…
- Archive.Context.replicationChannel must be set
- ControlSession.RESPONSE_NOT_CONNECTED_MSG + ": " + session
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/3a88ff6522b5e6d6.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/ReplicationSession.java:731
.fileIoMaxLength(fileIoMaxLength)
.replayToken(replayToken);
final ArchiveProxy archiveProxy = null != responseArchiveProxy ?
responseArchiveProxy : srcArchive.archiveProxy();
if (archiveProxy.replay(
srcRecordingId,
channelUri.toString(),
replayStreamId,
replayParams,
correlationId,
srcArchive.controlSessionId()))
{
workCount += trackAction(correlationId);
}
else if (epochClock.time() >= (timeOfLastActionMs + actionTimeoutMs))
{
throw new TimeoutException("failed to send replay request");
}
}
else
{
final ControlResponsePoller poller = srcArchive.controlResponsePoller();
workCount += poller.poll();
if (hasResponse(poller))
{
srcReplaySessionId = poller.relevantId();
state(State.AWAIT_IMAGE, "srcReplaySessionId=" + srcReplaySessionId);
}
else if (epochClock.time() >= (timeOfLastActionMs + actionTimeoutMs))
{
throw new TimeoutException("failed get acknowledgement of replay request to: " + replicationChannel);
}
}
View on GitHub (pinned to 6d60124e15)