aeron-io/aeron · error · ArchiveException
failed to send replicate request
Error message
failed to send replicate request
What it means
Thrown when a replicate request could not be offered to the archive control publication. ArchiveProxy.replicate returned false after retrying the offer, so the archive never received the instruction to replicate the source recording. This signals a control-session/transport failure rather than a replication configuration problem.
Solutions
- Re-establish the archive session (AeronArchive.connect) and retry the replicate call.
- Validate srcControlChannel is reachable from the destination archive before calling replicate.
- Check the Aeron error log and archive logs for publication connection failures or back-pressure; fix channel config accordingly.
- Add retry with backoff around replicate when operating over WAN links.
- Confirm both source and destination archives are running compatible Aeron versions.
Example fix
// before
long replicationId = archive.replicate(srcRecordingId, AeronArchive.NULL_POSITION, srcControlStreamId, srcControlChannel, null);
// after
long replicationId;
try {
replicationId = archive.replicate(srcRecordingId, AeronArchive.NULL_POSITION, srcControlStreamId, srcControlChannel, null);
} catch (ArchiveException e) {
if (e.message().contains("failed to send")) {
archive = reconnect(archive);
replicationId = archive.replicate(srcRecordingId, AeronArchive.NULL_POSITION, srcControlStreamId, srcControlChannel, null);
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (archive == null || archive.context().isClosed()) { archive = AeronArchive.connect(ctx); } // and verify srcControlChannel reachable Type guard
static boolean isSendFailure(ArchiveException e) { return e.getMessage() != null && e.getMessage().contains("failed to send"); } Try / catch
try { long id = archive.replicate(src, dst, srcStreamId, srcChannel, liveDest); } catch (ArchiveException e) { if (isSendFailure(e)) { archive = reconnect(archive); /* retry once */ } else { throw e; } } Prevention
- Validate source archive connectivity before starting replication.
- Use bounded retries with backoff for WAN replication control calls.
- Dedicate a control session to replication orchestration.
- Keep Aeron versions aligned between source and destination archives.
When it happens
Trigger: Calling AeronArchive.replicate(srcRecordingId, dstRecordingId, srcControlStreamId, srcControlChannel, liveDestination) while the control session is closed, the archive is unreachable, or the publication is back-pressured past the retry limit.
Common situations: Source archive control channel (srcControlChannel) unreachable at replication setup time; archive restarting; cross-datacenter control channel with high latency causing persistent back-pressure; stale AeronArchive handle reused after session expiry.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- failed to send tagged replicate request
- failed to send stop replication request
- failed to send invalidate recording request
- failed to send list recording subscriptions request
- failed to send detach segments request
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/28fe155c04944f03.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java:1829
{
lock.lock();
try
{
ensureConnected();
ensureNotReentrant();
lastCorrelationId = aeron.nextCorrelationId();
if (!archiveProxy.replicate(
srcRecordingId,
dstRecordingId,
srcControlStreamId,
srcControlChannel,
liveDestination,
lastCorrelationId,
controlSessionId))
{
throw new ArchiveException("failed to send replicate request");
}
return pollForResponse(lastCorrelationId);
}
finally
{
lock.unlock();
}
}
/**
* Replicate a recording from a source archive to a destination which can be considered a backup for a primary
* archive. The source recording will be replayed via the provided replay channel and use the original stream id.
* If the destination recording id is {@link io.aeron.Aeron#NULL_VALUE} then a new destination recording is created,
* otherwise the provided destination recording id will be extended. The details of the source recording
* descriptor will be replicated.
* <p>
* For a source recording that is still active the replay can merge with the live stream and then follow itView on GitHub (pinned to 6d60124e15)