alibaba/nacos · error · IllegalArgumentException

Token secret key change requires restart

Error message

Token secret key change requires restart

What it means

The token secret key is the HMAC key for every issued JWT; changing it at runtime would invalidate all outstanding tokens instantly and is therefore refused. applyTokenConfig() compares the currently-applied key against the freshly-read one and throws IllegalArgumentException if they differ and a key was already applied. The only supported way to rotate the key is a full server restart so all in-memory token state is rebuilt consistently.

Source

Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/token/TokenManagerDelegate.java:65

    }
    
    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;
        } else if (shouldClearCache(current)) {
            cachedTokenManager.clear();
        }
        lastAppliedConfig = current;
    }
    
    private boolean shouldClearCache(NacosAuthPluginConfig current) {
        return lastAppliedConfig.getTokenExpireSeconds() != current.getTokenExpireSeconds()
            || lastAppliedConfig.isTokenCacheEnabled() != current.isTokenCacheEnabled();
    }
    
    /**

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Do not hot-swap the secret key. To rotate: set the new key in config, then restart every Nacos node in a coordinated maintenance window.
  2. If hit during a failed hot reload, revert the key to the previous value and restart the node.
  3. Distribute the same key to all cluster members before restarting to avoid cross-node token mismatch.
  4. After rotation, force clients to re-login (old tokens are invalid).

Example fix

// before (hot reload triggers the error)
// config change event -> applyTokenConfig() -> IllegalArgumentException

// after: rotate only via restart
// 1. set nacos.plugin.auth.nacos.token.secret.key=<newKey> in application.properties
// 2. stop all nodes
// 3. start all nodes (applyTokenConfig runs once with the new key, lastAppliedConfig==null)
Defensive patterns

Strategy: validation

Validate before calling

// Reject secret-key changes at config-load time instead of letting applyTokenConfig throw.
String newKey = configProvider.getConfig().getTokenSecretKey();
String appliedKey = lastAppliedConfig == null ? null : lastAppliedConfig.getTokenSecretKey();
if (appliedKey != null && !Objects.equals(appliedKey, newKey)) {
    log.error("token secret key changed at runtime; restart required. Refusing hot reload.");
    // do NOT call applyTokenConfig() with the new key
}

Try / catch

try {
    delegate.applyTokenConfig();
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("secret key change")) {
        log.error("secret key rotation requires restart; reverting");
        // revert config to previous key and schedule restart
    }
    throw e;
}

Prevention

When it happens

Trigger: Editing nacos.plugin.auth.nacos.token.secret.key in application.properties (or via a config-change event) while the server is running, then triggering a refresh that calls applyTokenConfig() a second time with the new key.

Common situations: Operator rotates the secret key via hot reload expecting tokens to keep working; an external config manager pushes a new key to a live node; clustered nodes given divergent keys one at a time.

Related errors


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