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

  1. Ensure applyTokenConfig() is invoked during plugin startup (e.g. in a @PostConstruct or the auth plugin init hook) before any token API is exposed.
  2. In tests, call delegate.applyTokenConfig() right after constructing it.
  3. Delay accepting auth-bound traffic until the plugin reports ready; check server startup logs for the auth-plugin-initialized marker.
  4. 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

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


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/e9b9973e0a6f54f6. Report an issue: GitHub.