{"record":{"id":"32492bdf7937cc64","repo":"aeron-io/aeron","slug":"unknown-counter","errorCode":"UNKNOWN_COUNTER","errorMessage":"unknown counter: ${registrationId}","messagePattern":"unknown counter: (.+?)","errorType":"error_code","errorClass":"ControlProtocolException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java","lineNumber":961,"sourceCode":"\n    void onRemoveCounter(final long registrationId, final long correlationId)\n    {\n        CounterLink counterLink = null;\n        final ArrayList<CounterLink> counterLinks = this.counterLinks;\n        for (int i = 0, size = counterLinks.size(); i < size; i++)\n        {\n            final CounterLink link = counterLinks.get(i);\n            if (registrationId == link.registrationId())\n            {\n                counterLink = link;\n                fastUnorderedRemove(counterLinks, i);\n                break;\n            }\n        }\n\n        if (null == counterLink)\n        {\n            throw new ControlProtocolException(UNKNOWN_COUNTER, \"unknown counter: \" + registrationId);\n        }\n\n        clientProxy.operationSucceeded(correlationId);\n        clientProxy.onUnavailableCounter(registrationId, counterLink.counterId());\n        counterLink.close();\n    }\n\n    void onClientClose(final long clientId)\n    {\n        final AeronClient client = findClient(clients, clientId);\n        if (null != client)\n        {\n            client.onClosedByCommand();\n        }\n    }\n\n    void onAddRcvDestination(final long registrationId, final String destinationChannel, final long correlationId)\n    {","sourceCodeStart":943,"sourceCodeEnd":979,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java#L943-L979","documentation":"Thrown by DriverConductor when a removeCounter command references a counter registrationId that has no matching CounterLink in the driver. The driver looks up the counter among its active links; if none matches it throws ControlProtocolException with code UNKNOWN_COUNTER, so the client's remove operation fails and no onUnavailableCounter/operationSucceeded is issued for it.","triggerScenarios":"Calling CountersReader/ClientConductor releaseCounter or Aeron.removeCounter() with an id that was never allocated, already released, or whose counter was freed when its owning client was timed out by the driver.","commonSituations":"Double-releasing counters in shutdown code; using a counter id (int) instead of the registrationId (long); releasing after driver restart; counters closed automatically on client timeout then released again by app code.","solutions":["Pass counter.registrationId() (the long registration id), not the counterId int, to removeCounter","Release each counter once; guard double-release paths by nulling the reference after release","Catch ControlProtocolException with UNKNOWN_COUNTER and treat as already-released during cleanup","Verify the counter still exists via CountersReader before removal (check its state is not RECORD_RECLAIMED)"],"exampleFix":"// before\nlong id = counter.counterId(); // wrong: int counterId, not registrationId\naeron.removeCounter(id);\n// after\ntry {\n    aeron.removeCounter(counter.registrationId());\n} catch (ControlProtocolException e) {\n    if (e.errorCode() == ControlProtocolException.Code.UNKNOWN_COUNTER) {\n        // counter already released\n    } else { throw e; }\n}","handlingStrategy":"try-catch","validationCode":"final CountersReader counters = aeron.countersReader();\nif (counters.getCounterState(counter.counterId()) != CountersReader.RECORD_ALLOCATED) { return; }","typeGuard":"boolean isCounterLive(CountersReader r, Counter c) { return !c.isClosed() && r.getCounterState(c.counterId()) == CountersReader.RECORD_ALLOCATED; }","tryCatchPattern":"try {\n    aeron.removeCounter(counter.registrationId());\n} catch (ControlProtocolException e) {\n    if (e.errorCode() != ControlProtocolException.Code.UNKNOWN_COUNTER) throw e;\n    // already released\n}","preventionTips":["Use registrationId() (long), never counterId() (int), for removal","Null out counter references after release to prevent double-release","Check counter state via CountersReader before releasing","Release counters on the same client that allocated them"],"tags":["aeron","driver","counter","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"}