aeron-io/aeron · error · ConfigurationException
Must use Aeron.Context.useConductorAgentInvoker(true) when…
Error message
Must use Aeron.Context.useConductorAgentInvoker(true) when Aeron.Context.clientLock(...) is using a NoOpLock
What it means
Aeron.Context throws this ConfigurationException during configuration when a NoOpLock is set as the client lock via clientLock(...) but useConductorAgentInvoker(true) was not enabled. NoOpLock provides no mutual exclusion, which is only safe when the caller drives the conductor agent directly on the same thread (agent invoker mode); otherwise concurrent access is unsafe, so the combination is rejected.
Solutions
- Call ctx.useConductorAgentInvoker(true) on the same Context that uses NoOpLock
- Remove the NoOpLock and use the default ReentrantLock if you want the normal client thread mode
- Use the Convenience/ Configuration helper that pairs clientLock(true) with useConductorAgentInvoker(true) consistently
Example fix
// before
Aeron.Context ctx = new Aeron.Context()
.clientLock(new NoOpLock());
Aeron aeron = Aeron.connect(ctx); // throws
// after
Aeron.Context ctx = new Aeron.Context()
.clientLock(new NoOpLock())
.useConductorAgentInvoker(true);
Aeron aeron = Aeron.connect(ctx); Defensive patterns
Strategy: validation
Validate before calling
if (ctx instanceof Aeron.Context) { /* ensure pairing before connect */ } // validate: use NoOpLock only together with useConductorAgentInvoker(true) Type guard
boolean lockModeConsistent(Aeron.Context ctx) { return ctx.useConductorAgentInvoker() || !(ctx.clientLock() instanceof NoOpLock); } Try / catch
try { return Aeron.connect(ctx); } catch (ConfigurationException e) { if (e.getMessage().contains("NoOpLock")) { ctx.useConductorAgentInvoker(true); return Aeron.connect(ctx); } throw e; } Prevention
- Always pair clientLock(new NoOpLock()) with useConductorAgentInvoker(true)
- Write a Context factory that enforces the pairing in one place
- Never mix dedicated-mode configs with invoker-mode clients
When it happens
Trigger: Building a Context with ctx.clientLock(new NoOpLock()) (or ctx.clientLock(true) equivalent) without also calling ctx.useConductorAgentInvoker(true), then calling Aeron.connect(ctx).
Common situations: Low-latency setups that eliminate locking to avoid contention but forget to switch to conductor agent invoker mode; copying a dedicated-mode config into a client that still uses the driver thread; upgrades where NoOpLock was introduced and existing configs were not updated.
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
- Archive.Context.threadingMode(ArchiveThreadingMode.INVOKER)…
- Must use Aeron.Context.useConductorAgentInvoker(true) when…
- Aeron client must use conductor agent invoker
- catalogFileSyncLevel
- invalid fileIoMaxLength=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/3ceacb12d14cd102.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/Aeron.java:1184
/**
* This is called automatically by {@link Aeron#connect(Aeron.Context)} and its overloads.
* There is no need to call it from a client application. It is responsible for providing default
* values for options that are not individually changed through field setters.
*
* @return this for a fluent API.
*/
@SuppressWarnings("checkstyle:methodlength")
public Context conclude()
{
super.conclude();
if (null == clientLock)
{
clientLock = new ReentrantLock();
}
else if (clientLock instanceof NoOpLock && !useConductorAgentInvoker)
{
throw new ConfigurationException(
"Must use Aeron.Context.useConductorAgentInvoker(true) when Aeron.Context.clientLock(...) " +
"is using a NoOpLock");
}
if (null != driverAgentInvoker && !useConductorAgentInvoker)
{
throw new ConfigurationException(
"Must use Aeron.Context.useConductorAgentInvoker(true) when Aeron.Context.driverAgentInvoker() " +
"is set");
}
if (clientName.length() > MAX_CLIENT_NAME_LENGTH)
{
throw new ConfigurationException("clientName length must <= " + MAX_CLIENT_NAME_LENGTH);
}
if (null == epochClock)
{View on GitHub (pinned to 6d60124e15)