aeron-io/aeron · error · AeronException

Aeron client is terminating

Error message

Aeron client is terminating

What it means

ClientConductor.assertOpenAndNotTerminating() throws this when any public Aeron client API is called after the conductor has begun terminating (either close() was called or an internal error triggered termination). Once isTerminating is set the client is shutting down and no further API calls are permitted. It guards resource management against use-after-close.

Solutions

  1. Ensure close() is the last operation: shut down all threads that use Aeron before closing
  2. Keep a single owner/lifecycle for the Aeron client and check isClosed() before API calls
  3. If triggered by an internal timeout termination, investigate the earlier root-cause exception (driver timeout)
  4. Restart the client: create a new Aeron instance instead of reusing the closed one

Example fix

// before
executor.shutdown();
aeron.close();
executor.awaitTermination(5, TimeUnit.SECONDS); // workers still using aeron after close
// after
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
aeron.close();
Defensive patterns

Strategy: try-catch

Validate before calling

if (aeron.isClosed()) { throw new IllegalStateException("Aeron client already closed"); }

Type guard

boolean usable(Aeron a) { return a != null && !a.isClosed(); }

Try / catch

try { publication.offer(buffer); } catch (AeronException e) { if (e.getMessage().contains("terminating")) { reconnectClient(); } else { throw e; } }

Prevention

When it happens

Trigger: Calling any Aeron client API (addPublication, addSubscription, nextCorrelationId, etc.) after Aeron.close(), after the conductor self-terminated due to a driver timeout, or from a shutdown hook racing close().

Common situations: Publishers/subscriptions used from daemon threads that outlive the Aeron client; shutdown ordering issues where the JVM closes Aeron while worker threads still send; calling close() twice with a subsequent operation.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/ClientConductor.java:1720

            clientLock.unlock();
        }
    }

    void onNextAvailableSessionId(final int nextSessionId)
    {
        lastResponseValue = nextSessionId;
    }

    private void ensureActive()
    {
        if (isClosed)
        {
            throw new AeronException("Aeron client is closed");
        }

        if (isTerminating)
        {
            throw new AeronException("Aeron client is terminating");
        }
    }

    private void ensureNotReentrant()
    {
        if (isInCallback)
        {
            throw new AeronException("reentrant calls not permitted during callbacks");
        }
    }

    private LogBuffers logBuffers(final long registrationId, final String logFileName, final String channel)
    {
        LogBuffers logBuffers = logBuffersByIdMap.get(registrationId);
        if (null == logBuffers)
        {
            try
            {

View on GitHub (pinned to 6d60124e15)