alibaba/nacos · critical · IllegalStateException
Nacos auth plugin has not been initialized
Error message
Nacos auth plugin has not been initialized
What it means
TokenManagerDelegate lazily resolves its real delegate via getExecuteTokenManager(), which requires applyTokenConfig() to have run at least once to populate both tokenManager and cachedTokenManager. If any createToken/parseToken/validateToken call reaches the delegate before that initialization completes, it throws IllegalStateException. This is a lifecycle defect: a token operation arrived before the auth plugin finished bootstrapping.
Source
Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/token/TokenManagerDelegate.java:53
public class TokenManagerDelegate implements TokenManager {
private final NacosAuthPluginConfigProvider configProvider;
private volatile JwtTokenManager tokenManager;
private volatile CachedJwtTokenManager cachedTokenManager;
private NacosAuthPluginConfig lastAppliedConfig;
public TokenManagerDelegate(NacosAuthPluginConfigProvider configProvider) {
this.configProvider = configProvider;
}
private TokenManager getExecuteTokenManager() {
JwtTokenManager direct = tokenManager;
CachedJwtTokenManager cached = cachedTokenManager;
if (direct == null || cached == null) {
throw new IllegalStateException("Nacos auth plugin has not been initialized");
}
return configProvider.getConfig().isTokenCacheEnabled() ? cached : direct;
}
/**
* Initialize token managers once and clear cached state after relevant config changes.
*/
public synchronized void applyTokenConfig() {
NacosAuthPluginConfig current = configProvider.getConfig();
if (lastAppliedConfig != null && !Objects.equals(lastAppliedConfig.getTokenSecretKey(),
current.getTokenSecretKey())) {
throw new IllegalArgumentException("Token secret key change requires restart");
}
if (tokenManager == null) {
JwtTokenManager direct = new JwtTokenManager(configProvider);
CachedJwtTokenManager cached = new CachedJwtTokenManager(direct, configProvider);
tokenManager = direct;
cachedTokenManager = cached;View on GitHub (pinned to 9b989acdf1)
Solutions
- Ensure applyTokenConfig() is invoked during plugin startup (e.g. in a @PostConstruct or the auth plugin init hook) before any token API is exposed.
- In tests, call delegate.applyTokenConfig() right after constructing it.
- Delay accepting auth-bound traffic until the plugin reports ready; check server startup logs for the auth-plugin-initialized marker.
- If seen in production, restart the affected node so the init hook runs cleanly.
Example fix
// before
TokenManagerDelegate delegate = new TokenManagerDelegate(configProvider);
String token = delegate.createToken("alice"); // throws IllegalStateException
// after
TokenManagerDelegate delegate = new TokenManagerDelegate(configProvider);
delegate.applyTokenConfig(); // must run first
String token = delegate.createToken("alice"); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the delegate is initialized before any token operation.
TokenManagerDelegate delegate = new TokenManagerDelegate(configProvider);
delegate.applyTokenConfig(); // MUST run before createToken/parseToken/validateToken
// If you cannot call it directly, guard usage:
try {
delegate.parseToken(token);
} catch (IllegalStateException e) {
log.error("auth plugin not initialized; init ordering bug");
} Try / catch
try {
nacosUser = tokenManager.parseToken(token);
} catch (IllegalStateException e) {
// plugin not initialized yet -> fail closed, do not serve authed traffic
log.error("auth plugin not initialized: {}", e.getMessage());
throw new ServiceUnavailableException("authentication service is starting");
} Prevention
- Call applyTokenConfig() in the auth plugin's @PostConstruct before exposing token APIs.
- In tests, always invoke applyTokenConfig() right after constructing the delegate.
- Delay auth-bound traffic until startup completes.
- Treat this as fail-closed: never bypass auth when uninitialized.
When it happens
Trigger: A login or token-validation request arrives during server startup before the auth plugin's applyTokenConfig() init hook fires; a unit test new'd TokenManagerDelegate directly without calling applyTokenConfig(); a Spring bean-ordering problem where the delegate is injected and used before its initializer bean runs.
Common situations: Early client traffic during a rolling restart hitting a node whose auth plugin has not finished init; custom integration tests that construct the delegate manually; bean wiring error omitting the config-init bean.
Related errors
- the length of secret key must great than or equal 32 bytes;
- user not found!
- token invalid!
- token expired!
- Token secret key change requires restart
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/e9b9973e0a6f54f6.
Report an issue: GitHub.