aeron-io/aeron · error · AeronException

client is closed

Error message

client is closed

What it means

Aeron.nextCorrelationId allocates ids from the client's driver command buffer; if the client has been closed, the command buffer is gone, so the method throws AeronException 'client is closed'. Callers must not use an Aeron instance after close().

Solutions

  1. Ensure the Aeron instance outlives all users, or guard calls with aeron.isClosed() / isClosed flag
  2. Synchronize shutdown so all threads stop publishing/requesting before Aeron.close()
  3. Recreate the Aeron instance (Aeron.connect) if the driver restarted
  4. Use try-with-resources or a lifecycle manager for Aeron

Example fix

// before
long id = aeron.nextCorrelationId(); // may throw after close
// after
if (aeron.isClosed()) { aeron = Aeron.connect(ctx); }
long id = aeron.nextCorrelationId();
Defensive patterns

Strategy: try-catch

Validate before calling

if (aeron == null || aeron.isClosed()) { aeron = Aeron.connect(ctx); }

Type guard

boolean isUsable(Aeron aeron) { return aeron != null && !aeron.isClosed(); }

Try / catch

try { long id = aeron.nextCorrelationId(); }
catch (AeronException e) { if ("client is closed".equals(e.getMessage())) { aeron = Aeron.connect(ctx); id = aeron.nextCorrelationId(); } }

Prevention

When it happens

Trigger: Calling aeron.nextCorrelationId() after Aeron.close() or after the client was closed by the driver (e.g. driver termination or ERROR injection leading to client close).

Common situations: Shutdown races where a background thread still issues commands while the main thread closes Aeron; holding a stale Aeron reference after a driver restart; long-lived caches storing Aeron instances.

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/379317acc679141d. Report an issue: GitHub.

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/Aeron.java:497

    {
        return conductor.getSubscription(registrationId);
    }

    /**
     * Generate the next correlation id that is unique for the connected media driver.
     * <p>
     * This is useful generating correlation identifiers for pairing requests with responses in a clients own
     * application protocol.
     * <p>
     * This method is thread safe and will work across processes that all use the same media driver.
     *
     * @return next correlation id that is unique for the media driver.
     */
    public long nextCorrelationId()
    {
        if (isClosed)
        {
            throw new AeronException("client is closed");
        }

        return commandBuffer.nextCorrelationId();
    }

    /**
     * Get next available session id from the media driver. The session id will be unique for the connected media
     * driver and given {@code streamId}.
     * <p>
     * If media driver's version is 1.49.0 or higher, then the session id is returned by the media driver. Otherwise,
     * a random session id is generated.
     *
     * @param streamId for which a new session id is requested. Media driver only checks for session clashes at the
     *                 stream level.
     * @return next available session id that is unique for the media driver and given {@code streamId}.
     * @since 1.49.0
     */
    public int nextSessionId(final int streamId)

View on GitHub (pinned to 6d60124e15)