aeron-io/aeron · error · ArchiveException
authenticator cannot be null
Error message
authenticator cannot be null
What it means
ArchiveConductor obtains the Authenticator by calling ctx.authenticatorSupplier().get() at startup. The archive requires a real authenticator even if no authentication is needed (use a no-op one), so a null result is rejected with ArchiveException. This guards against suppliers that return null by default.
Solutions
- Fix the authenticatorSupplier to return a non-null Authenticator instance.
- If authentication is not required, supply a permissive no-op Authenticator (e.g. a singleton that always authorises).
- Use Archive.Configuration.authenticatorSupplier() default, which returns a valid no-op authenticator.
Example fix
// before
ctx.authenticatorSupplier(() -> null);
// after
ctx.authenticatorSupplier(() -> new Authenticator()
{
public void onConnectRequest(...) { session.response(...); /* accept */ }
public void onChallengeResponse(...) { }
public void onConnectedSession(Session session) { session.accept(); }
public void onChallengedSession(Session session) { }
}); Defensive patterns
Strategy: validation
Validate before calling
Authenticator a = ctx.authenticatorSupplier().get();
if (a == null)
{
throw new IllegalStateException("authenticatorSupplier must return a non-null Authenticator");
} Prevention
- Never write suppliers that return null; return a no-op/permissive Authenticator instead
- Test archive startup with the real supplier wiring before deployment
When it happens
Trigger: Launching Archive with an authenticatorSupplier whose get() returns null (e.g. a lambda that fails to instantiate, or a default supplier returning null).
Common situations: Custom AuthenticationSupplier implementations with broken lazy initialization;DI frameworks injecting null when no bean is defined.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- authorisation service cannot be null
- Aeron client instance must set…
- Aeron client must use a RethrowingErrorHandler
- segment file length not a power of 2
- segment file length not in valid range
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/67d30c54f2c63a6f.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/ArchiveConductor.java:212
aeron = ctx.aeron();
aeronAgentInvoker = aeron.conductorAgentInvoker();
driverAgentInvoker = ctx.mediaDriverAgentInvoker();
epochClock = ctx.epochClock();
nanoClock = ctx.nanoClock();
archiveDir = ctx.archiveDir();
connectTimeoutMs = TimeUnit.NANOSECONDS.toMillis(ctx.connectTimeoutNs());
sessionLivenessCheckIntervalMs = TimeUnit.NANOSECONDS.toMillis(ctx.sessionLivenessCheckIntervalNs());
catalog = ctx.catalog();
markFile = ctx.archiveMarkFile();
dutyCycleTracker = ctx.conductorDutyCycleTracker();
cachedEpochClock.update(epochClock.time());
random = ctx.secureRandom();
authenticator = ctx.authenticatorSupplier().get();
if (null == authenticator)
{
throw new ArchiveException("authenticator cannot be null");
}
authorisationService = ctx.authorisationServiceSupplier().get();
if (null == authorisationService)
{
throw new ArchiveException("authorisation service cannot be null");
}
unavailableCounterHandlerRegistrationId = aeron.addUnavailableCounterHandler(this);
closeHandlerRegistrationId = aeron.addCloseHandler(this::abort);
recordingEventsProxy = ctx.recordingEventsEnabled() ? new RecordingEventsProxy(
aeron.addExclusivePublication(ctx.recordingEventsChannel(), ctx.recordingEventsStreamId())) : null;
if (ctx.controlChannelEnabled())
{
final ChannelUri controlChannelUri = ChannelUri.parse(ctx.controlChannel());
controlChannelUri.put(CommonContext.SPARSE_PARAM_NAME, Boolean.toString(ctx.controlTermBufferSparse()));View on GitHub (pinned to 6d60124e15)