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
- 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
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
- 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
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
- UNKNOWN_PUBLICATION
- UNKNOWN_COUNTER
- unknown MDS subscription
- image.correlationId=
- unknown MDS subscription
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)