{"record":{"id":"bfa5f22567f301cf","repo":"aeron-io/aeron","slug":"failed-to-write-remove-subscription-command","errorCode":null,"errorMessage":"failed to write remove subscription command","messagePattern":"failed to write remove subscription command","errorType":"exception","errorClass":"AeronException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/java/io/aeron/DriverProxy.java","lineNumber":201,"sourceCode":"\n        toDriverCommandBuffer.commit(index);\n\n        return correlationId;\n    }\n\n    /**\n     * Instruct the driver to remove a subscription by its registration id.\n     *\n     * @param registrationId for the subscription to be removed.\n     * @return the correlation id for the command.\n     */\n    public long removeSubscription(final long registrationId)\n    {\n        final long correlationId = toDriverCommandBuffer.nextCorrelationId();\n        final int index = toDriverCommandBuffer.tryClaim(REMOVE_SUBSCRIPTION, RemoveSubscriptionFlyweight.length());\n        if (index < 0)\n        {\n            throw new AeronException(\"failed to write remove subscription command\");\n        }\n\n        removeSubscriptionFlyweight\n            .wrap(toDriverCommandBuffer.buffer(), index)\n            .registrationId(registrationId)\n            .clientId(clientId)\n            .correlationId(correlationId);\n\n        toDriverCommandBuffer.commit(index);\n\n        return correlationId;\n    }\n\n    /**\n     * Add a destination to the send channel of an existing MDC Publication.\n     *\n     * @param registrationId  of the Publication.\n     * @param endpointChannel for the destination.","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/DriverProxy.java#L183-L219","documentation":"DriverProxy.removeSubscription() throws AeronException when tryClaim(REMOVE_SUBSCRIPTION, length) cannot reserve space in the client-to-driver command buffer, so the removal command could not be written. Like removePublication, Aeron fails fast because a failed removal would leave driver-side state inconsistent with the client.","triggerScenarios":"Calling Subscription.close() (or Aeron.removeSubscription) while the driver is dead/blocked and the command buffer is full; also during client conductor shutdown racing with subscription release.","commonSituations":"Application shutdown where the driver was stopped first; driver conductor stalled by a slow image-unavailable handler; runaway add/remove subscription churn overflowing the buffer.","solutions":["Close subscriptions before stopping the media driver in your shutdown sequence.","Make driver-side handler callbacks non-blocking so command consumption never stalls.","Wrap close() calls in try-catch during shutdown when the driver may already be gone."],"exampleFix":"// before\nsubscription.close();\naeron.close();\ndriver.close();\n// after\nsubscription.close();\naeron.close();\ndriver.close(); // driver closed last\n// plus: try { subscription.close(); } catch (AeronException e) { /* driver already gone */ }","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n    subscription.close();\n} catch (AeronException e) {\n    log.warn(\"removeSubscription failed during shutdown\", e);\n}","preventionTips":["Follow shutdown order: close subscriptions, then client, then driver.","Keep driver handlers non-blocking.","Avoid rapid add/remove subscription churn; reuse subscriptions where possible."],"tags":["aeron","driver-communication","ring-buffer-full","command-buffer"],"backgroundTag":"broken-pipe","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"}