aeron-io/aeron · critical · AgentTerminationException

unexpected Aeron close

Error message

unexpected Aeron close

What it means

ConsensusModuleAgent.idle() is the agent duty-cycle idle hook. Before idling it checks whether the underlying Aeron client has been closed by an external actor; if so the agent cannot continue and throws AgentTerminationException so the consensus module shuts down cleanly instead of operating on a dead client.

Solutions

  1. Determine why the Aeron client closed: check the media driver logs for errors/timeout and keep the driver alive for the cluster's lifetime.
  2. Ensure no application code closes the shared Aeron instance while the consensus module agent is running.
  3. Shut down the consensus module as part of the same lifecycle as the Aeron client so close ordering is deliberate.
  4. Check for driver timeout configuration (driverTimeoutMs) mismatch with slow GC/paging on the host.

Example fix

// before
driver.close(); // closes media driver, Aeron client dies under the agent
// after
consensusModule.close();
driver.close(); // close cluster components before the driver
Defensive patterns

Strategy: try-catch

Validate before calling

// before starting the agent
if (aeron.isClosed()) { throw new IllegalStateException("Aeron client closed before cluster agent start"); }

Try / catch

try { consensusModule.start(); } catch (AgentTerminationException e) { log.fatal("Aeron client closed: check media driver health", e); shutdownCluster(); }

Prevention

When it happens

Trigger: While the consensus module agent is idle (no work count), aeron.isClosed() returns true because someone called aeron.close() or a fatal error closed the client (e.g. driver death, uncuched client error, driver timeout).

Common situations: Media driver terminated or crashed while the consensus module kept running; another thread closed the shared Aeron client; driver heartbeat timeout due to a stalled or frozen system.

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

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModuleAgent.java:535

        return clusterTimeUnit;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IdleStrategy idleStrategy()
    {
        return this;
    }

    public void idle()
    {
        checkInterruptStatus();
        aeronClientInvoker.invoke();
        if (aeron.isClosed())
        {
            throw new AgentTerminationException("unexpected Aeron close");
        }

        idleStrategy.idle();
        pollArchiveEvents();
    }

    public void idle(final int workCount)
    {
        checkInterruptStatus();
        aeronClientInvoker.invoke();
        if (aeron.isClosed())
        {
            throw new AgentTerminationException("unexpected Aeron close");
        }

        idleStrategy.idle(workCount);

        if (0 == workCount)

View on GitHub (pinned to 6d60124e15)