aeron-io/aeron · error · ClusterException
Aeron client must use a RethrowingErrorHandler
Error message
Aeron client must use a RethrowingErrorHandler
What it means
ClusterBackup drives its media driver interactions from within an agent and requires the Aeron client's subscriber error handler to be a RethrowingErrorHandler, so client errors propagate to the backup agent instead of being swallowed by a default logging handler. conclude() throws this ClusterException when a custom (non-rethrowing) error handler is configured on the Aeron context.
Solutions
- Use RethrowingErrorHandler.INSTANCE as the subscriber error handler on the Aeron.Context used by the backup.
- Create a dedicated Aeron client for the ClusterBackup rather than reusing one configured for the application.
- Move custom error logging to a wrapper that still rethrows, or handle errors via the supplied errorCounter/AgentListener instead.
Example fix
// before Aeron.Context aeronCtx = new Aeron.Context().subscriberErrorHandler(myLoggingHandler); // after Aeron.Context aeronCtx = new Aeron.Context().subscriberErrorHandler(RethrowingErrorHandler.INSTANCE);
Defensive patterns
Strategy: validation
Validate before calling
if (!(aeronCtx.subscriberErrorHandler() instanceof RethrowingErrorHandler)) { throw new IllegalStateException("backup requires RethrowingErrorHandler"); } Type guard
static boolean usesRethrowingHandler(Aeron.Context c) { return c.subscriberErrorHandler() instanceof RethrowingErrorHandler; } Try / catch
try {
ctx.conclude();
} catch (ClusterException e) {
if (e.getMessage().contains("RethrowingErrorHandler")) { log.error("configure Aeron.Context with RethrowingErrorHandler.INSTANCE"); }
throw e;
} Prevention
- Use a dedicated Aeron.Context for ClusterBackup with RethrowingErrorHandler.INSTANCE
- Do not globally replace subscriber error handlers on clients shared with the backup
- Surface errors via errorCounter/AgentListener instead of swallowing handlers
When it happens
Trigger: Concluding a ClusterBackup.Context after supplying an Aeron instance whose context error handler was replaced (aeron.context().subscriberErrorHandler(customHandler)) with anything other than RethrowingErrorHandler.INSTANCE.
Common situations: Sharing an application-wide Aeron client configured with a logging error handler; copying driver/client setup code that sets a custom ErrorHandler; embedding ClusterBackup in an app with centralized error swallowing.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Aeron client must use conductor agent invoker
- Aeron client must use a RethrowingErrorHandler
- Aeron client must use conductor agent invoker
- error counter must be supplied if aeron client is
- catalogFileSyncLevel
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/34d5d15b5ee2ea0c.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterBackup.java:789
.clientLock(NoOpLock.INSTANCE)
.clientName(clientName));
if (null == errorCounter)
{
errorCounter = ClusterCounters.allocateVersioned(
aeron,
buffer,
"ClusterBackup Errors",
CLUSTER_BACKUP_ERROR_COUNT_TYPE_ID,
clusterId,
ClusterBackupVersion.VERSION,
ClusterBackupVersion.GIT_SHA);
}
}
if (!(aeron.context().subscriberErrorHandler() instanceof RethrowingErrorHandler))
{
throw new ClusterException("Aeron client must use a RethrowingErrorHandler");
}
if (!aeron.context().useConductorAgentInvoker())
{
throw new ClusterException("Aeron client must use conductor agent invoker");
}
if (null == errorCounter)
{
throw new ClusterException("error counter must be supplied if aeron client is");
}
if (null == countedErrorHandler)
{
countedErrorHandler = new CountedErrorHandler(errorHandler, errorCounter);
if (ownsAeronClient)
{
aeron.context().errorHandler(countedErrorHandler);View on GitHub (pinned to 6d60124e15)