{"record":{"id":"7ebbbeef0d06cff9","repo":"aeron-io/aeron","slug":"failed-to-send-replay-request-aeronarchive","errorCode":null,"errorMessage":"failed to send replay request","messagePattern":"failed to send replay request","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java","lineNumber":1046,"sourceCode":"    {\n        lock.lock();\n        try\n        {\n            ensureConnected();\n            ensureNotReentrant();\n\n            lastCorrelationId = aeron.nextCorrelationId();\n\n            if (!archiveProxy.replay(\n                recordingId,\n                position,\n                length,\n                replayChannel,\n                replayStreamId,\n                lastCorrelationId,\n                controlSessionId))\n            {\n                throw new ArchiveException(\"failed to send replay request\");\n            }\n\n            return pollForResponse(lastCorrelationId);\n        }\n        finally\n        {\n            lock.unlock();\n        }\n    }\n\n    /**\n     * Start a replay for a length in bytes of a recording from a position bounded by a position counter.\n     * If the position is {@link #NULL_POSITION} then the stream will be replayed from the start.\n     * <p>\n     * The lower 32-bits of the returned value contains the {@link Image#sessionId()} of the received replay. All\n     * 64-bits are required to uniquely identify the replay when calling {@link #stopReplay(long)}. The lower 32-bits\n     * can be obtained by casting the {@code long} value to an {@code int}.\n     *","sourceCodeStart":1028,"sourceCodeEnd":1064,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java#L1028-L1064","documentation":"startReplay issues a REPLAY control request via ArchiveProxy.replay. The proxy returns false when the control-request publication is not connected or the offer fails, meaning the replay request never reached the archive. The client throws this ArchiveException before polling for the replay session id.","triggerScenarios":"Calling startReplay(recordingId, position, length, replayChannel, replayStreamId) with the archive control channel disconnected, backpressured, or the control session publication closed (archive restart, network fault).","commonSituations":"Replay pipelines started right after archive failover; replayChannel URI typos causing downstream failures that cascade into control-channel disconnects; long-running clients whose control session timed out.","solutions":["Confirm the archive is running and the control channel is connected.","Re-establish the AeronArchive session and retry startReplay.","Retry with backoff for transient backpressure on the control stream.","Verify replayChannel/replayStreamId arguments before retrying to rule out client-side config errors."],"exampleFix":"// before\nlong sessionId = archive.startReplay(recordingId, pos, len, replayChannel, streamId);\n\n// after\nlong sessionId;\ntry {\n    sessionId = archive.startReplay(recordingId, pos, len, replayChannel, streamId);\n} catch (ArchiveException e) {\n    archive = AeronArchive.connect(archiveCtx);\n    sessionId = archive.startReplay(recordingId, pos, len, replayChannel, streamId);\n}","handlingStrategy":"retry","validationCode":"// validate inputs and connectivity before startReplay\nif (recordingId <= 0 || length < 0) throw new IllegalArgumentException(\"bad replay args\");\ntry (AeronArchive ignored = AeronArchive.connect(archiveCtx)) {}","typeGuard":"boolean connected(AeronArchive a) { return a != null && !a.isClosed() && a.state() == AeronArchive.State.CONNECTED; }","tryCatchPattern":"try {\n    long sid = archive.startReplay(recordingId, pos, len, ch, streamId);\n} catch (ArchiveException e) {\n    archive = AeronArchive.connect(archiveCtx);\n    retryWithBackoff(() -> archive.startReplay(recordingId, pos, len, ch, streamId));\n}","preventionTips":["Health-check the archive before replay pipelines start.","Retry transient send failures with backoff.","Keep control-channel config in sync between client and archive.","Avoid sharing one control session across many threads under heavy load."],"tags":["aeron","archive","replay","network"],"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"}