aeron-io/aeron · warning · AgentTerminationException

interrupted

Error message

interrupted

What it means

checkInterruptStatus throws AgentTerminationException when the current thread's interrupt flag is set. Long-running cluster operations (elections, catchup, snapshots) check this regularly so the agent shuts down promptly on interruption instead of continuing in a degraded state.

Solutions

  1. Find what interrupted the thread (executor shutdown, shutdown hook) and confirm it is intentional
  2. If shutting down, let the container close cleanly; this error is expected during shutdown
  3. Avoid using interrupt-based timeouts against cluster agents; use AgentRunner close instead
  4. Restart the agent after the shutdown completes if the interruption was accidental

Example fix

// before: interrupting the agent to stop it
agentRunner.agent().interrupt();

// after: close the runner gracefully
agentRunner.close();
Defensive patterns

Strategy: try-catch

Try / catch

catch (AgentTerminationException e)
{
    if ("interrupted".equals(e.getMessage()))
    {
        log.info("agent interrupted, shutting down cleanly");
        Thread.interrupted(); // clear flag before optional re-launch
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: Thrown whenever the agent thread is interrupted, e.g. during idle() calls or blocking waits, after another thread called Thread.interrupt() on the agent.

Common situations: Container/executor shutdown calling shutdownNow(); JVM shutdown hooks interrupting agents; test frameworks cancelling long-running cluster agents; timeouts implemented via interrupt.

Related errors


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

Appendix: source

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

            leadershipTermId,
            termBaseLogPosition,
            commitPosition,
            appendedPosition,
            activeMembers,
            clusterMemberByIdMap,
            thisMember,
            consensusPublisher,
            ctx,
            this);

        election.doWork(clusterClock.timeNanos());
    }

    private static void checkInterruptStatus()
    {
        if (Thread.currentThread().isInterrupted())
        {
            throw new AgentTerminationException("interrupted");
        }
    }

    private void snapshotOnServiceAck(final long logPosition, final long timestamp, final ServiceAck[] serviceAcks)
    {
        if (isSnapshotSetComplete(serviceAcks))
        {
            try
            {
                takeSnapshot(timestamp, logPosition, serviceAcks);
            }
            catch (final RuntimeException ex)
            {
                ctx.countedErrorHandler().onError(new ClusterException("failed to take snapshot", ex));
                if (ex instanceof AgentTerminationException ||
                    ex instanceof ArchiveException ae && ArchiveException.STORAGE_SPACE == ae.errorCode())
                {
                    unexpectedTermination(ex.getMessage());

View on GitHub (pinned to 6d60124e15)