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
- Ensure close() is the last operation: shut down all threads that use Aeron before closing
- Keep a single owner/lifecycle for the Aeron client and check isClosed() before API calls
- If triggered by an internal timeout termination, investigate the earlier root-cause exception (driver timeout)
- 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
- Shut down all producer/consumer threads before Aeron.close()
- Use a single lifecycle owner for the client
- Check isClosed() before API calls in mixed-thread code
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
- client is closed
- client is closed
- counter id is not allocated, state
- reentrant calls not permitted during callbacks
- unexpected interrupt
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)