aeron-io/aeron · warning · ControlProtocolException

RESOURCE_TEMPORARILY_UNAVAILABLE

RESOURCE_TEMPORARILY_UNAVAILABLE

Error message

SendChannelEndpoint found in CLOSING state, please retry

What it means

While adding a network publication the driver found the existing SendChannelEndpoint for the same channel in the CLOSING state. Because the endpoint is being torn down concurrently, the request cannot be processed now; the driver throws a ControlProtocolException with code RESOURCE_TEMPORARILY_UNAVAILABLE, telling the client the operation succeeded but must be retried shortly.

Solutions

  1. Retry the addPublication()/channel setup after a short backoff until the endpoint finishes closing.
  2. Treat error code RESOURCE_TEMPORARILY_UNAVAILABLE as retryable in your Aeron exception handler.
  3. Avoid close-then-immediately-reopen on the same channel URI; reuse the existing publication where possible.
  4. Poll the publication/endpoint status before re-adding on the same URI.

Example fix

// before
publication.close();
Publication p = aeron.addPublication(sameUri, streamId); // may hit CLOSING
// after
publication.close();
Retry: while (true) {
  try { Publication p = aeron.addPublication(sameUri, streamId); break Retry; }
  catch (ControlProtocolException e) { if (e.errorCode() != RESOURCE_TEMPORARILY_UNAVAILABLE) throw e; Thread.sleep(50); }
}
Defensive patterns

Strategy: retry

Validate before calling

// Poll endpoint status before re-adding, or serialize close/add with the driver's client lock and small delay:
Thread.sleep(100); // after close(), before addPublication on the same URI

Try / catch

catch (ControlProtocolException e) {
  if (e.errorCode() == AeronException.Category.ERROR.getCode() && e.getMessage().contains("CLOSING state")) {
    backoffAndRetryAddPublication(uri, streamId); // exponential backoff, e.g. 50ms..1s
  } else throw e;
}

Prevention

When it happens

Trigger: Rapidly closing and immediately re-adding a publication on the same channel URI (e.g. close(oldPub); addPublication(sameUri)) while the driver conductor is still closing the old endpoint.

Common situations: Reconnect/retry loops that churn publications; test suites that recreate publications quickly; failover logic recreating senders after connection loss.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:2486

        {
        }
    }

    private abstract static class ClientCommand extends Command
    {
        final long correlationId;

        private ClientCommand(final long correlationId)
        {
            this.correlationId = correlationId;
        }
    }

    private static void throwResourceTemporaryUnavailableIfEndpointIsClosing(final SendChannelEndpoint endpoint)
    {
        if (ChannelEndpointStatus.CLOSING == endpoint.status())
        {
            throw new ControlProtocolException(
                RESOURCE_TEMPORARILY_UNAVAILABLE,
                "SendChannelEndpoint found in CLOSING state, please retry");
        }
    }

    private static void throwResourceTemporaryUnavailableIfEndpointIsClosing(final ReceiveChannelEndpoint endpoint)
    {
        if (ChannelEndpointStatus.CLOSING == endpoint.status())
        {
            throw new ControlProtocolException(
                RESOURCE_TEMPORARILY_UNAVAILABLE,
                "ReceiveChannelEndpoint found in CLOSING state, please retry");
        }
    }

    private final class AddNetworkPublicationCommand extends ClientCommand
    {
        private final String channel;

View on GitHub (pinned to 6d60124e15)