aeron-io/aeron · error · AeronException

failed to write remove rcv destination command

Error message

failed to write remove rcv destination command

What it means

DriverProxy.removeRcvDestination claims space in the toDriverCommandBuffer to write a REMOVE_RCV_DESTINATION command. A negative tryClaim return means the ring buffer had no room for the message, so the command was never enqueued and AeronException is thrown. This indicates client-to-driver command backpressure or a non-consuming driver.

Solutions

  1. Confirm the media driver is alive and its agent thread is consuming commands
  2. Retry removeRcvDestination after a short backoff if the driver is only momentarily slow
  3. Throttle bulk destination removals (e.g., small sleep or batching between calls)
  4. For embedded drivers, ensure the driver agent thread is not blocked and enlarge the command queue if consistently saturated
  5. Treat repeated failures as driver death: close the client and reconnect/restart the driver

Example fix

// before
subscription.removeRcvDestination(channel);
// after
if (!driverProxy.isActive()) throw new IllegalStateException("driver stopped");
awaitCommandBufferDrained(); // ensure ring has capacity before claiming
subscription.removeRcvDestination(channel);
Defensive patterns

Strategy: retry

Validate before calling

if (!aeron.context().isDriverActive()) {
    throw new IllegalStateException("driver inactive; removeRcvDestination would fail");
}

Try / catch

try {
    subscription.removeRcvDestination(channel);
} catch (AeronException e) {
    if (!e.getMessage().startsWith("failed to write")) throw e;
    // retry with backoff; abort after N attempts
}

Prevention

When it happens

Trigger: Calling Subscription.removeRcvDestination when the driver command ring is full — driver dead, paused (GC/debugger), or the client issued many commands in a tight loop faster than the driver drains.

Common situations: Driver terminated while client teardown code removes MDC destinations; bulk removal of many destinations in shutdown code; embedded driver agent thread blocked, leaving the command queue saturated.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/6d5b54df7c4dd43e. Report an issue: GitHub.

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/DriverProxy.java:345

        return correlationId;
    }

    /**
     * Remove a destination from the receive channel endpoint of an existing MDS Subscription.
     *
     * @param registrationId  of the Subscription.
     * @param endpointChannel used for the {@link #addRcvDestination(long, String)} command.
     * @return the correlation id for the command.
     */
    public long removeRcvDestination(final long registrationId, final String endpointChannel)
    {
        final long correlationId = toDriverCommandBuffer.nextCorrelationId();
        final int length = DestinationMessageFlyweight.computeLength(endpointChannel.length());
        final int index = toDriverCommandBuffer.tryClaim(REMOVE_RCV_DESTINATION, length);
        if (index < 0)
        {
            throw new AeronException("failed to write remove rcv destination command");
        }

        destinationMessageFlyweight
            .wrap(toDriverCommandBuffer.buffer(), index)
            .registrationCorrelationId(registrationId)
            .channel(endpointChannel)
            .clientId(clientId)
            .correlationId(correlationId);

        toDriverCommandBuffer.commit(index);

        return correlationId;
    }

    /**
     * Add a new counter with a type id plus the label and key are provided in buffers.
     *
     * @param typeId      for associating with the counter.

View on GitHub (pinned to 6d60124e15)