aeron-io/aeron · error · AeronException
failed to write remove counter command
Error message
failed to write remove counter command
What it means
DriverProxy.removeCounter claims space in the toDriverCommandBuffer to write a REMOVE_COUNTER command for a previously allocated counter registration id. tryClaim returned negative because the ring lacked capacity for RemoveCounterFlyweight.length() bytes, so AeronException is thrown and the release command was never sent to the driver.
Solutions
- Confirm the media driver is running and consuming commands
- Retry removeCounter with backoff — the failure is transient if the driver is merely slow
- Stagger bulk counter release (e.g., close in small batches)
- If the driver is dead, accept the leak on the driver side and restart; the counter dies with the driver
- Check client ErrorHandler logs for earlier signs of driver liveness loss
Example fix
// before
aeron.removeCounter(registrationId);
// after
try {
aeron.removeCounter(registrationId);
} catch (AeronException e) {
if (!"failed to write remove counter command".equals(e.getMessage())) throw e;
// driver cannot accept commands; log and proceed with shutdown —
// the driver (if restarted) will free the counter as an orphan
LOG.warn("driver not accepting commands; counter " + registrationId + " left to driver cleanup");
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!aeron.context().isDriverActive()) {
// counter will be freed when driver restarts; skip sending release
return;
} Try / catch
try {
aeron.removeCounter(registrationId);
} catch (AeronException e) {
if (!e.getMessage().startsWith("failed to write")) throw e;
// log and continue shutdown; orphaned counter is reclaimed by driver restart
} Prevention
- Release counters during normal operation, not only in crash-time cleanup
- Close counters in small batches during mass shutdown
- Confirm driver health before expecting release commands to succeed
- Accept orphaned counters on driver loss — they die with the driver
- Watch ErrorHandler for driver-liveness loss early
When it happens
Trigger: Calling Counter.close() / Aeron.removeCounter(registrationId) when the command ring is full — driver not consuming (crashed, GC stall, debugger pause) or bulk counter releases outpacing the driver.
Common situations: Application shutdown releasing many counters at once while the driver is already overloaded; driver process terminated mid-run; test harnesses creating and freeing hundreds of counters rapidly.
Related errors
- failed to write add counter command
- failed to write add rcv destination command
- failed to write remove rcv destination command
- failed to write reject image command
- failed to write next session id command
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/c57a93850700bf95.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/DriverProxy.java:444
toDriverCommandBuffer.commit(index);
return correlationId;
}
/**
* Instruct the media driver to remove an existing counter by its registration id.
*
* @param registrationId of counter to remove.
* @return the correlation id for the command.
*/
public long removeCounter(final long registrationId)
{
final long correlationId = toDriverCommandBuffer.nextCorrelationId();
final int index = toDriverCommandBuffer.tryClaim(REMOVE_COUNTER, RemoveCounterFlyweight.length());
if (index < 0)
{
throw new AeronException("failed to write remove counter command");
}
removeCounterFlyweight
.wrap(toDriverCommandBuffer.buffer(), index)
.registrationId(registrationId)
.clientId(clientId)
.correlationId(correlationId);
toDriverCommandBuffer.commit(index);
return correlationId;
}
/**
* Notify the media driver that this client is closing.
*/
public void clientClose()
{View on GitHub (pinned to 6d60124e15)