{"record":{"id":"0a82cd7fc5fc5f79","repo":"aeron-io/aeron","slug":"failed-to-offer-async-replay-response","errorCode":null,"errorMessage":"failed to offer async replay response","messagePattern":"failed to offer async replay response","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/ControlSession.java","lineNumber":743,"sourceCode":"            queueResponse(correlationId, relevantId, code, errorMessage);\n        }\n        else\n        {\n            activityDeadlineMs = NULL_VALUE;\n        }\n    }\n\n    void asyncSendOkResponse(final long correlationId, final long replaySessionId)\n    {\n        if (!asyncResponseQueue.offer(() -> controlResponseProxy.sendResponse(\n            controlSessionId,\n            correlationId,\n            replaySessionId,\n            OK,\n            null,\n            this)))\n        {\n            throw new IllegalStateException(\"failed to offer async replay response\");\n        }\n    }\n\n    boolean sendDescriptor(final long correlationId, final UnsafeBuffer descriptorBuffer)\n    {\n        assertCalledOnConductorThread();\n        final boolean sent =\n            controlResponseProxy.sendDescriptor(controlSessionId, correlationId, descriptorBuffer, this);\n        if (!sent)\n        {\n            updateActivityDeadline(cachedEpochClock.time());\n        }\n        else\n        {\n            activityDeadlineMs = NULL_VALUE;\n        }\n        return sent;\n    }","sourceCodeStart":725,"sourceCodeEnd":761,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/ControlSession.java#L725-L761","documentation":"ControlSession.asyncSendOkResponse throws IllegalStateException when the internal offer of an async replay's OK response (via the control response proxy) fails, i.e. the response could not be enqueued for delivery to the client. This indicates the session's response publication could not accept the message at the moment of the offer.","triggerScenarios":"Calling asyncSendOkResponse (e.g. to acknowledge a start-replay request) when the response publication offer fails — publication back-pressured/blocked, not connected, closed, or at max position, so the OK reply cannot be offered.","commonSituations":"Client disconnected just as the replay start was accepted; response publication back-pressured by a slow consumer; session being closed concurrently by the conductor; response channel misconfigured so no subscriber is attached.","solutions":["Ensure the client keeps its control-response subscription open until it receives the OK reply for the replay request","On failure, the archive conductor should abort/close the session so the client reconnects and retries the replay request","Check client-side consumption: a stalled poller thread on the response subscription causes persistent back-pressure","Verify control response channel connectivity (endpoints, networks, driver running) on both sides"],"exampleFix":"// client-side retry pattern\nlong correlationId = archive.startReplay(...);\n// poll with timeout; on failure reconnect and resubmit\nif (!awaitOk(archive, correlationId, timeoutMs))\n{\n    archive.close();\n    archive = ArchiveProxy.connect(controlResponseChannel);\n    correlationId = archive.startReplay(...);\n}","handlingStrategy":"retry","validationCode":"if (controlSession == null || controlSession.isClosed()) { throw new IllegalStateException(\"control session not usable for async replay response\"); }","typeGuard":null,"tryCatchPattern":"try { session.asyncSendOkResponse(correlationId, replaySessionId); }\ncatch (IllegalStateException e)\n{\n    if (e.getMessage().contains(\"failed to offer async replay response\")) { /* abort session / client retries request */ }\n    else { throw e; }\n}","preventionTips":["Keep the client response subscription polled so back-pressure never blocks offers","Retry briefly on back-pressure before treating the offer as failed (archive-side)","Ensure replay requests are only issued on a healthy, connected control session","Verify response channel configuration and network path before starting replays"],"tags":["java","aeron-archive","replay","publication","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"}