aeron-io/aeron · error · UnknownSubscriptionException

unknown subscription

Error message

unknown subscription: ${registrationId}

What it means

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.

Solutions

  1. Pass the registrationId returned by the addSubscription future and remove each subscription exactly once
  2. Wrap removal in try-catch for UnknownSubscriptionException and treat it as idempotent success during teardown
  3. Ensure the same Aeron client instance that added the subscription performs the removal
  4. Check client keepalive settings (aeron.client.liveness.timeout) so slow apps don't have subscriptions reaped mid-flight

Example fix

// before
aeron.removeSubscription(subscription.registrationId());
// after
try {
    aeron.removeSubscription(subscription.registrationId());
} catch (UnknownSubscriptionException e) {
    // already removed or client reaped it - safe to ignore during cleanup
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (subscription.isClosed()) { return; } // already removed or reaped

Type guard

boolean isRemovable(Subscription s) { return s != null && !s.isClosed(); }

Try / catch

try {
    aeron.removeSubscription(subscription.registrationId());
} catch (UnknownSubscriptionException e) {
    // already gone - ignore during teardown
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/528bc51321aca44d. Report an issue: GitHub.

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:869

    void onRemoveSubscription(final long registrationId, final long correlationId)
    {
        boolean isAnySubscriptionFound = false;
        for (int lastIndex = subscriptionLinks.size() - 1, i = lastIndex; i >= 0; i--)
        {
            final SubscriptionLink subscription = subscriptionLinks.get(i);
            if (subscription.registrationId() == registrationId)
            {
                fastUnorderedRemove(subscriptionLinks, i, lastIndex--);

                subscription.close();
                cleanupSubscriptionLink(subscription);
                isAnySubscriptionFound = true;
            }
        }

        if (!isAnySubscriptionFound)
        {
            throw new UnknownSubscriptionException("unknown subscription: " + registrationId);
        }

        clientProxy.operationSucceeded(correlationId);
    }

    void onClientKeepalive(final long clientId)
    {
        final AeronClient client = findClient(clients, clientId);
        if (null != client)
        {
            client.timeOfLastKeepaliveMs(cachedEpochClock.time());
        }
    }

    void onAddCounter(
        final int typeId,
        final DirectBuffer keyBuffer,
        final int keyOffset,

View on GitHub (pinned to 6d60124e15)