{"record":{"id":"9ddcc85a87f3bdb4","repo":"aeron-io/aeron","slug":"counter-id-counterid-is-not-allocated-state-state","errorCode":null,"errorMessage":"counter id <counterId> is not allocated, state: <state>","messagePattern":"counter id <counterId> is not allocated, state: <state>","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/java/io/aeron/AeronCounters.java","lineNumber":1606,"sourceCode":"     * {@link CountersReader#MAX_LABEL_LENGTH}.\n     *\n     * @param metaDataBuffer containing the counter metadata.\n     * @param counterId      to append version info to.\n     * @param value          to be appended to the label.\n     * @return number of bytes that got appended.\n     * @throws IllegalArgumentException if {@code counterId} is invalid or points to non-allocated counter.\n     */\n    public static int appendToLabel(\n        final AtomicBuffer metaDataBuffer, final int counterId, final String value)\n    {\n        Objects.requireNonNull(metaDataBuffer);\n        validateCounterId(metaDataBuffer, counterId);\n\n        final int counterMetaDataOffset = metaDataOffset(counterId);\n        final int state = metaDataBuffer.getIntVolatile(counterMetaDataOffset);\n        if (RECORD_ALLOCATED != state)\n        {\n            throw new IllegalArgumentException(\"counter id \" + counterId + \" is not allocated, state: \" + state);\n        }\n\n        final int existingLabelLength = metaDataBuffer.getInt(counterMetaDataOffset + LABEL_OFFSET);\n        final int remainingLabelLength = MAX_LABEL_LENGTH - existingLabelLength;\n\n        final int writtenLength = metaDataBuffer.putStringWithoutLengthAscii(\n            counterMetaDataOffset + LABEL_OFFSET + SIZE_OF_INT + existingLabelLength,\n            value,\n            0,\n            remainingLabelLength);\n        if (writtenLength > 0)\n        {\n            metaDataBuffer.putIntRelease(\n                counterMetaDataOffset + LABEL_OFFSET, existingLabelLength + writtenLength);\n        }\n\n        return writtenLength;\n    }","sourceCodeStart":1588,"sourceCodeEnd":1624,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/AeronCounters.java#L1588-L1624","documentation":"Thrown by Aeron counter metadata APIs (e.g. setting/updating a counter label) when the given counterId's metadata record is not in RECORD_ALLOCATED state. Aeron validates that a counter was actually allocated via a Counter/CounterManager before its metadata can be mutated. The state value in the message shows the raw metadata record state (e.g. RECORD_UNUSED=0, RECORD_RECLAIMED).","triggerScenarios":"Calling a public AeronCounters method (e.g. updateLabel/setLabel style APIs) with a counterId that was never allocated, or whose record was freed/reclaimed via a prior free/release call.","commonSituations":"Using a counter id from a closed Counter object; double-freeing then touching a counter; race where another thread frees the counter before the label update; passing a hardcoded or guessed counter id instead of one obtained from Counter.counterId().","solutions":["Obtain the counterId from the Counter instance returned by Aeron.addCounter() and use it before calling close()/free.","Verify the counter is still allocated: check its state via the counters reader (isAllocated / getCounterState) before mutating metadata.","Audit for double-free logic: ensure the counter is not released by another thread or cleanup path before use.","Wrap the call in try-catch for IllegalArgumentException and treat it as 'counter no longer allocated' if reclamation is expected in your design."],"exampleFix":"// before\nlong id = 7; // guessed\naeron.counters().updateLabel(id, \"new label\");\n// after\ntry (Counter counter = aeron.addCounter(1, \"my counter\")) {\n    aeron.counters().updateLabel(counter.counterId(), \"new label\");\n}","handlingStrategy":"validation","validationCode":"if (counterId < 0 || !countersReader.isAllocated(counterId)) {\n    throw new IllegalStateException(\"counter \" + counterId + \" not allocated\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    aeronCounters.updateLabel(counterId, label);\n} catch (IllegalArgumentException e) {\n    // counter was freed or never allocated; re-acquire or skip\n}","preventionTips":["Always take counterId from Counter.counterId(), never hardcode","Check CountersReader.isAllocated before metadata mutations","Avoid touching counters after close/free; track lifecycle ownership","Beware races: one thread freeing while another updates"],"tags":["aeron","counters","illegal-argument","lifecycle"],"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"}