{"record":{"id":"1007b12ab5c7298f","repo":"aeron-io/aeron","slug":"controlsession-response-not-connected-msg-session","errorCode":null,"errorMessage":"ControlSession.RESPONSE_NOT_CONNECTED_MSG + \": \" + session","messagePattern":"ControlSession\\.RESPONSE_NOT_CONNECTED_MSG \\+ \": \" \\+ session","errorType":"exception","errorClass":"ArchiveEvent","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/ControlResponseProxy.java","lineNumber":247,"sourceCode":"            final long position = session.controlPublication().offer(buffer, 0, length);\n            if (position > 0)\n            {\n                return true;\n            }\n\n            checkResult(session, position);\n        }\n        while (--attempts > 0);\n\n        return false;\n    }\n\n    private static void checkResult(final ControlSession session, final long result)\n    {\n        if (result == Publication.NOT_CONNECTED)\n        {\n            session.abort(ControlSession.RESPONSE_NOT_CONNECTED_MSG);\n            throw new ArchiveEvent(ControlSession.RESPONSE_NOT_CONNECTED_MSG + \": \" + session);\n        }\n\n        if (result == Publication.CLOSED)\n        {\n            session.abort(\"control response publication is closed\");\n            throw new ArchiveEvent(\"response publication is closed: \" + session, AeronException.Category.ERROR);\n        }\n\n        if (result == Publication.MAX_POSITION_EXCEEDED)\n        {\n            session.abort(\"control response publication is at max position\");\n            throw new ArchiveEvent(\n                \"response publication is at max position: \" + session, AeronException.Category.ERROR);\n        }\n    }\n\n    private void logSendResponse(final DirectBuffer buffer, final int offset, final int length)\n    {","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/ControlResponseProxy.java#L229-L265","documentation":"ControlResponseProxy.checkResult throws ArchiveEvent with ControlSession.RESPONSE_NOT_CONNECTED_MSG when sending a control response on the session's publication returns Publication.NOT_CONNECTED. This means the client's control-response image has no active subscriber — the client is no longer connected to the archive's response channel, so the reply cannot be delivered.","triggerScenarios":"Calling sendDescriptor, sendResponse, or send on ControlResponseProxy when the underlying control response Publication offers to zero connected subscribers (NOT_CONNECTED), e.g. the client closed its subscription or its media driver went away mid-request.","commonSituations":"Client application crashed or closed its Aeron connection while a challenge/response or descriptor send was in flight; network/UDP path dropped so the publication has no receivers; client timed out and tore down its subscription while archive still tries to reply.","solutions":["Treat ArchiveEvent with the not-connected message as a client-gone condition: archive-side code should catch it and clean up the session rather than retry aggressively","On the client, ensure the control-response subscription is established and remains open for the duration of archive requests","Check network connectivity and driver status on the client before/around archive operations","Re-issue the archive request from the client after re-establishing a fresh control session"],"exampleFix":"// archive-side handling\ntry\n{\n    controlResponseProxy.sendResponse(controlSessionId, correlationId, relevantId, code, message, controlSession);\n}\ncatch (ArchiveEvent e)\n{\n    if (e.getMessage().startsWith(ControlSession.RESPONSE_NOT_CONNECTED_MSG))\n    {\n        // client no longer connected; close session instead of retrying\n        controlSession.close();\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (aeron.clientVersion() != null && !archiveProxy.isConnected()) { /* reconnect control session before sending requests */ }","typeGuard":"boolean sessionAlive(ControlSession s) { return s != null && !s.isClosed(); }","tryCatchPattern":"try { proxy.sendResponse(...); }\ncatch (ArchiveEvent e)\n{\n    if (e.getMessage().startsWith(ControlSession.RESPONSE_NOT_CONNECTED_MSG)) { session.close(); }\n    else { throw e; }\n}","preventionTips":["Keep the control-response subscription polled continuously while archive requests are outstanding","Detect client shutdown and cancel pending archive requests before closing Aeron","Monitor Publication.isConnected() on the response channel","Reconnect and retry with a new session after connectivity is restored"],"tags":["java","aeron-archive","publication","not-connected","network"],"backgroundTag":"connection-refused","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"}