{"record":{"id":"528bc51321aca44d","repo":"aeron-io/aeron","slug":"unknown-subscription-registrationid","errorCode":null,"errorMessage":"unknown subscription: ${registrationId}","messagePattern":"unknown subscription: (.+?)","errorType":"exception","errorClass":"UnknownSubscriptionException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java","lineNumber":869,"sourceCode":"    void onRemoveSubscription(final long registrationId, final long correlationId)\n    {\n        boolean isAnySubscriptionFound = false;\n        for (int lastIndex = subscriptionLinks.size() - 1, i = lastIndex; i >= 0; i--)\n        {\n            final SubscriptionLink subscription = subscriptionLinks.get(i);\n            if (subscription.registrationId() == registrationId)\n            {\n                fastUnorderedRemove(subscriptionLinks, i, lastIndex--);\n\n                subscription.close();\n                cleanupSubscriptionLink(subscription);\n                isAnySubscriptionFound = true;\n            }\n        }\n\n        if (!isAnySubscriptionFound)\n        {\n            throw new UnknownSubscriptionException(\"unknown subscription: \" + registrationId);\n        }\n\n        clientProxy.operationSucceeded(correlationId);\n    }\n\n    void onClientKeepalive(final long clientId)\n    {\n        final AeronClient client = findClient(clients, clientId);\n        if (null != client)\n        {\n            client.timeOfLastKeepaliveMs(cachedEpochClock.time());\n        }\n    }\n\n    void onAddCounter(\n        final int typeId,\n        final DirectBuffer keyBuffer,\n        final int keyOffset,","sourceCodeStart":851,"sourceCodeEnd":887,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java#L851-L887","documentation":"Thrown by DriverConductor when a client sends a removeSubscription command whose registrationId matches no SubscriptionLink in the driver's subscriptionLinks list. Unlike the publication case this throws UnknownSubscriptionException (a subclass of ControlProtocolException), and it is raised before the operationSucceeded ack is sent. The driver only knows subscriptions that are currently registered for the connected client.","triggerScenarios":"Calling Aeron.removeSubscription() with an id that was never registered, was already removed, or whose subscription was auto-closed when the owning client hit its keepalive timeout (onClientKeepalive reaping).","commonSituations":"Removing the same subscription twice during shutdown; reusing registration ids saved before a driver restart; id mix-ups between MDS and regular subscriptions; removing a subscription from a different Aeron client than the one that added it.","solutions":["Pass the registrationId returned by the addSubscription future and remove each subscription exactly once","Wrap removal in try-catch for UnknownSubscriptionException and treat it as idempotent success during teardown","Ensure the same Aeron client instance that added the subscription performs the removal","Check client keepalive settings (aeron.client.liveness.timeout) so slow apps don't have subscriptions reaped mid-flight"],"exampleFix":"// before\naeron.removeSubscription(subscription.registrationId());\n// after\ntry {\n    aeron.removeSubscription(subscription.registrationId());\n} catch (UnknownSubscriptionException e) {\n    // already removed or client reaped it - safe to ignore during cleanup\n}","handlingStrategy":"try-catch","validationCode":"if (subscription.isClosed()) { return; } // already removed or reaped","typeGuard":"boolean isRemovable(Subscription s) { return s != null && !s.isClosed(); }","tryCatchPattern":"try {\n    aeron.removeSubscription(subscription.registrationId());\n} catch (UnknownSubscriptionException e) {\n    // already gone - ignore during teardown\n}","preventionTips":["Remove subscriptions from the same Aeron client that created them","Track removal state to avoid double-remove during shutdown","Keep client keepalives flowing (don't block the client conductor thread) so subscriptions aren't reaped","Don't persist registrationIds across driver restarts"],"tags":["aeron","driver","subscription","unknown-registration-id"],"backgroundTag":"resource-not-found","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"}