{"record":{"id":"673af091b78b63cf","repo":"aeron-io/aeron","slug":"failed-to-write-add-counter-command","errorCode":null,"errorMessage":"failed to write add counter command","messagePattern":"failed to write add counter command","errorType":"exception","errorClass":"AeronException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/java/io/aeron/DriverProxy.java","lineNumber":386,"sourceCode":"     * @param labelOffset offset at which the label begins.\n     * @param labelLength length in bytes for the label.\n     * @return the correlation id for the command.\n     */\n    public long addCounter(\n        final int typeId,\n        final DirectBuffer keyBuffer,\n        final int keyOffset,\n        final int keyLength,\n        final DirectBuffer labelBuffer,\n        final int labelOffset,\n        final int labelLength)\n    {\n        final long correlationId = toDriverCommandBuffer.nextCorrelationId();\n        final int length = CounterMessageFlyweight.computeLength(keyLength, labelLength);\n        final int index = toDriverCommandBuffer.tryClaim(ADD_COUNTER, length);\n        if (index < 0)\n        {\n            throw new AeronException(\"failed to write add counter command\");\n        }\n\n        counterMessageFlyweight\n            .wrap(toDriverCommandBuffer.buffer(), index)\n            .keyBuffer(keyBuffer, keyOffset, keyLength)\n            .labelBuffer(labelBuffer, labelOffset, labelLength)\n            .typeId(typeId)\n            .clientId(clientId)\n            .correlationId(correlationId);\n\n        toDriverCommandBuffer.commit(index);\n\n        return correlationId;\n    }\n\n    /**\n     * Add a new counter with a type id and label, the key will be blank.\n     *","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/DriverProxy.java#L368-L404","documentation":"DriverProxy.addCounter claims space in the toDriverCommandBuffer to write an ADD_COUNTER command carrying key and label buffers. tryClaim returned negative because the ring lacked capacity for CounterMessageFlyweight.computeLength(keyLength, labelLength) bytes, so AeronException is thrown. The counter was not created; the client could not hand the command to the driver.","triggerScenarios":"Calling Aeron.addCounter(name, keyBuffer, keyOffset, keyLength, labelBuffer, labelOffset, labelLength) (or via counter factory) when the command ring is full — driver not consuming, stalled, or a burst of counter allocations exceeded drain rate. Very large key/label lengths increase the space needed and make the failure more likely.","commonSituations":"Instrumentation code allocating hundreds of counters in a loop at startup while the driver is still initializing; driver process crashed; oversized counter labels approaching allocation limits filling the ring quickly.","solutions":["Check the media driver is running and consuming commands before allocating counters","Retry addCounter with backoff — the claim failure is transient if the driver is draining","Reduce the burst rate of counter creation; create counters lazily or in stages","Keep counter key/label sizes small to reduce required claim size","For embedded drivers, verify the driver agent thread health and increase command buffer capacity if saturation is recurring"],"exampleFix":"// before\nCounter c = aeron.addCounter( typeId, keyBuffer, 0, keyLength, labelBuffer, 0, labelLength);\n// after\nCounter c;\nint attempts = 0;\ndo {\n    try {\n        c = aeron.addCounter(typeId, keyBuffer, 0, keyLength, labelBuffer, 0, labelLength);\n        break;\n    } catch (AeronException e) {\n        if (++attempts > 5 || !driverProxy.isActive()) throw e;\n        Thread.sleep(10 * attempts);\n    }\n} while (true);","handlingStrategy":"retry","validationCode":"if (!aeron.context().isDriverActive()) {\n    throw new IllegalStateException(\"driver inactive; addCounter would fail\");\n}\nif (keyLength < 0 || labelLength < 0) {\n    throw new IllegalArgumentException(\"negative counter key/label length\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Counter c = aeron.addCounter(typeId, keyBuffer, keyOffset, keyLength, labelBuffer, labelOffset, labelLength);\n} catch (AeronException e) {\n    if (!e.getMessage().startsWith(\"failed to write\")) throw e;\n    // retry with exponential backoff while driver is active\n}","preventionTips":["Create counters lazily or in small batches, not in hot init loops","Keep counter keys and labels short","Ensure driver is consuming before counter-heavy instrumentation starts","Monitor driver GC pauses that stall command draining","Retry transient claim failures instead of crashing instrumentation"],"tags":["aeron","ipc","backpressure","counters"],"backgroundTag":"command-buffer-full","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"}