{"record":{"id":"68f11ada972ae555","repo":"aeron-io/aeron","slug":"failed-to-send-list-recording-subscriptions-request","errorCode":null,"errorMessage":"failed to send list recording subscriptions request","messagePattern":"failed to send list recording subscriptions request","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java","lineNumber":1773,"sourceCode":"        lock.lock();\n        try\n        {\n            ensureConnected();\n            ensureNotReentrant();\n\n            isInCallback = true;\n            lastCorrelationId = aeron.nextCorrelationId();\n\n            if (!archiveProxy.listRecordingSubscriptions(\n                pseudoIndex,\n                subscriptionCount,\n                channelFragment,\n                streamId,\n                applyStreamId,\n                lastCorrelationId,\n                controlSessionId))\n            {\n                throw new ArchiveException(\"failed to send list recording subscriptions request\");\n            }\n\n            return pollForSubscriptionDescriptors(lastCorrelationId, subscriptionCount, consumer);\n        }\n        finally\n        {\n            isInCallback = false;\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>","sourceCodeStart":1755,"sourceCodeEnd":1791,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java#L1755-L1791","documentation":"AeronArchive throws this when the listRecordingSubscriptions request could not be offered to the archive control publication. ArchiveProxy.listRecordingSubscriptions returned false because the offer failed after retries, meaning the archive never received the query. This is a control-channel transport failure, not an empty result.","triggerScenarios":"Calling listRecordingSubscriptions(cursor, subscriptionCount, channelFragment, streamId, applyStreamId, consumer) while the control session publication is closed, disconnected, or persistently back-pressured (offer retried to the limit and failed).","commonSituations":"Long-running archive client whose session was reaped by the archive; control channel congestion under heavy polling load; archive restarted while a listing client was idle; misconfigured control channel after a version/config change.","solutions":["Reconnect the archive client (close context, AeronArchive.connect(ctx)) and retry the listing.","Verify the control channel/stream configuration matches the running archive (aeron.archive.dir, control-channel in archive config).","Check archive logs and Aeron error log for publication CLOSED or back-pressure events around the failure.","Retry with backoff if the archive is temporarily overloaded; spread out polling calls.","Ensure a single thread owns the AeronArchive (it is not reentrant); concurrent use can corrupt session state leading to failed offers."],"exampleFix":"// before\nint count = archive.listRecordingSubscriptions(0, 10, \"\", streamId, false, consumer);\n// after\nint count;\ntry {\n    count = archive.listRecordingSubscriptions(0, 10, \"\", streamId, false, consumer);\n} catch (ArchiveException e) {\n    if (e.message().contains(\"failed to send\")) {\n        archive = reconnectQuietly(archive);\n        count = archive.listRecordingSubscriptions(0, 10, \"\", streamId, false, consumer);\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (archive == null || archive.context().isClosed()) { archive = AeronArchive.connect(ctx); }","typeGuard":"static boolean isSendFailure(ArchiveException e) { return e.getMessage() != null && e.getMessage().contains(\"failed to send\"); }","tryCatchPattern":"try { archive.listRecordingSubscriptions(0, n, fragment, streamId, applyStreamId, consumer); } catch (ArchiveException e) { if (isSendFailure(e)) { archive = reconnect(archive); } else { throw e; } }","preventionTips":["Throttle listing/polling frequency to avoid control-channel back-pressure.","Re-establish the session on send failures instead of looping on a dead handle.","Match client and archive control-channel configuration during upgrades.","Check archive uptime before issuing maintenance queries."],"tags":["aeron-archive","control-session","ipc-offer-failed","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"}