{"record":{"id":"f4b2d5c6f96e939d","repo":"aeron-io/aeron","slug":"unexpected-aeron-close","errorCode":null,"errorMessage":"unexpected Aeron close","messagePattern":"unexpected Aeron close","errorType":"exception","errorClass":"AgentTerminationException","httpStatus":null,"severity":"critical","filePath":"aeron-archive/src/main/java/io/aeron/archive/ArchiveConductor.java","lineNumber":371,"sourceCode":"        }\n        catch (final InterruptedException ignore)\n        {\n            Thread.currentThread().interrupt();\n        }\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public int doWork()\n    {\n        final long nowNs = nanoClock.nanoTime();\n        int workCount = 0;\n\n        if (isAbort)\n        {\n            throw new AgentTerminationException(\"unexpected Aeron close\");\n        }\n\n        dutyCycleTracker.measureAndUpdate(nowNs);\n\n        final long nowMs = epochClock.time();\n        if (cachedEpochClock.time() != nowMs)\n        {\n            cachedEpochClock.update(nowMs);\n            workCount += invokeAeronInvoker();\n\n            if (nowMs >= markFileUpdateDeadlineMs)\n            {\n                markFileUpdateDeadlineMs = nowMs + MARK_FILE_UPDATE_INTERVAL_MS;\n                markFile.updateActivityTimestamp(nowMs);\n            }\n        }\n\n        workCount += controlSessionAdapter.poll();","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/ArchiveConductor.java#L353-L389","documentation":"ArchiveConductor's doWork duty cycle detects that the owning Aeron client was closed (or an abort was requested) while the archive agent was still running. The library throws AgentTerminationException to shut down the archive agent immediately because it can no longer perform any useful work without a live Aeron client. This is a lifecycle violation, not a transient failure.","triggerScenarios":"Aeron.close() (or the context close) is called on the Aeron client used by the Archive while ArchiveConductor.doWork() is still being driven; or abort() is invoked on the conductor (e.g. during shutdown with a closed conductor).","commonSituations":"Application shuts down the Aeron client before stopping the Archive service; ordering mistake in a shutdown hook; using Aeron.connect() with an Archive that outlives the client; abrupt process shutdown racing the agent duty cycle.","solutions":["Ensure shutdown order: stop/close the Archive (archive.close()) before closing the Aeron client it was built with.","Reuse a single shared Aeron client for the Archive and do not close it while the archive agent is running.","In shutdown hooks, stop the agent runner driving doWork() first, then call aeron.close().","If abort was triggered externally, check whether your code calls archive.conductor().abort() or a forced termination path unintentionally.","Check for close() calls from other threads (multiple services sharing one Aeron instance) and remove the premature close."],"exampleFix":"// before\naeron.close();\narchive.close();\n\n// after\narchive.close();\naeron.close();","handlingStrategy":"try-catch","validationCode":"// before relying on archive\nif (aeron.isClosed()) {\n    throw new IllegalStateException(\"Aeron client closed; do not start Archive\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    archive = Archive.launch(ctx.client(aeron));\n} catch (AgentTerminationException e) {\n    log.error(\"Aeron client closed while archive running\", e);\n    // orderly shutdown: close archive then client\n}","preventionTips":["Always close Archive before the shared Aeron client.","Use try-with-resources with archive declared before aeron.","Do not share one Aeron client across independently-lifecycled services.","Centralize shutdown in one component to enforce ordering."],"tags":["aeron-archive","lifecycle","shutdown","agent"],"backgroundTag":"invalid-state-transition","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}