aeron-io/aeron · critical · AgentTerminationException
unexpected driver close
Error message
unexpected driver close
What it means
invokeDriverConductor runs the media driver's AgentInvoker inside the archive conductor. If after invoking it the driver invoker reports closed (driverAgentInvoker.isClosed()), the conductor throws AgentTerminationException("unexpected driver close"). The archive requires a live media driver and aborts when the driver goes away unexpectedly.
Solutions
- Ensure the media driver outlives the archive: close the Archive first, then the driver.
- Check driver logs for crash/OOM causing the driver agent to exit.
- If running an embedded driver, manage ordering in a single owner component (e.g. try-with-resources with driver declared last).
- If the driver is intentionally shut down, stop the Archive agent before closing the driver.
Example fix
// before driver.close(); archive.close(); // after archive.close(); driver.close();
Defensive patterns
Strategy: try-catch
Validate before calling
// guard before duty cycle
if (driverAgentInvoker != null && driverAgentInvoker.isClosed()) {
throw new AgentTerminationException("driver already closed");
} Try / catch
try {
conductor.doWork();
} catch (AgentTerminationException e) {
if (e.getMessage().contains("driver close")) {
log.error("Media driver closed unexpectedly; stopping archive agent", e);
}
} Prevention
- Close archive before driver in shutdown paths.
- Monitor driver process health (no OOM/kill).
- If using an external driver, verify it is up before launching the archive.
- Keep driver and archive lifecycles in one owner component.
When it happens
Trigger: Media driver is closed/crashes (driverAgentInvoker.isClosed() returns true) while ArchiveConductor.invokeDriverConductor() runs inside doWork().
Common situations: Embedded driver closed by another component first; driver process killed or exited (OOM, external kill); driver shut down via its own shutdown hook before the archive; use of a driver invoker bound to a closed driver context.
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
- unexpected Aeron close
- response publication is closed: " + session
- recording events publication is closed
- ConcurrentConcludeException
- client is closed
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/88a0befb1131180d.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/ArchiveConductor.java:436
isAbort = true;
throw new AgentTerminationException("unexpected Aeron close");
}
}
return workCount;
}
final int invokeDriverConductor()
{
int workCount = 0;
if (null != driverAgentInvoker)
{
workCount += driverAgentInvoker.invoke();
if (driverAgentInvoker.isClosed())
{
throw new AgentTerminationException("unexpected driver close");
}
}
return workCount;
}
void logWarning(final String message)
{
errorHandler.onError(new ArchiveEvent(message));
}
ControlSession newControlSession(
final Image image,
final long correlationId,
final int streamId,
final int version,
final String channel,
final byte[] encodedCredentials,View on GitHub (pinned to 6d60124e15)