{"record":{"id":"28fe155c04944f03","repo":"aeron-io/aeron","slug":"failed-to-send-replicate-request","errorCode":null,"errorMessage":"failed to send replicate request","messagePattern":"failed to send replicate request","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java","lineNumber":1829,"sourceCode":"    {\n        lock.lock();\n        try\n        {\n            ensureConnected();\n            ensureNotReentrant();\n\n            lastCorrelationId = aeron.nextCorrelationId();\n\n            if (!archiveProxy.replicate(\n                srcRecordingId,\n                dstRecordingId,\n                srcControlStreamId,\n                srcControlChannel,\n                liveDestination,\n                lastCorrelationId,\n                controlSessionId))\n            {\n                throw new ArchiveException(\"failed to send replicate request\");\n            }\n\n            return pollForResponse(lastCorrelationId);\n        }\n        finally\n        {\n            lock.unlock();\n        }\n    }\n\n    /**\n     * Replicate a recording from a source archive to a destination which can be considered a backup for a primary\n     * archive. The source recording will be replayed via the provided replay channel and use the original stream id.\n     * If the destination recording id is {@link io.aeron.Aeron#NULL_VALUE} then a new destination recording is created,\n     * otherwise the provided destination recording id will be extended. The details of the source recording\n     * descriptor will be replicated.\n     * <p>\n     * For a source recording that is still active the replay can merge with the live stream and then follow it","sourceCodeStart":1811,"sourceCodeEnd":1847,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java#L1811-L1847","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlong replicationId = archive.replicate(srcRecordingId, AeronArchive.NULL_POSITION, srcControlStreamId, srcControlChannel, null);\n// after\nlong replicationId;\ntry {\n    replicationId = archive.replicate(srcRecordingId, AeronArchive.NULL_POSITION, srcControlStreamId, srcControlChannel, null);\n} catch (ArchiveException e) {\n    if (e.message().contains(\"failed to send\")) {\n        archive = reconnect(archive);\n        replicationId = archive.replicate(srcRecordingId, AeronArchive.NULL_POSITION, srcControlStreamId, srcControlChannel, null);\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (archive == null || archive.context().isClosed()) { archive = AeronArchive.connect(ctx); } // and verify srcControlChannel reachable","typeGuard":"static boolean isSendFailure(ArchiveException e) { return e.getMessage() != null && e.getMessage().contains(\"failed to send\"); }","tryCatchPattern":"try { long id = archive.replicate(src, dst, srcStreamId, srcChannel, liveDest); } catch (ArchiveException e) { if (isSendFailure(e)) { archive = reconnect(archive); /* retry once */ } else { throw e; } }","preventionTips":["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."],"tags":["aeron-archive","replication","control-session","ipc-offer-failed"],"backgroundTag":"api-request-failed","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}