alibaba/nacos · error · AccessException

Invalid or expired state parameter

Error message

Invalid or expired state parameter

What it means

Thrown by AuthorizationCodeHandler.exchangeCodeForUser when verifyAndDecodeState(state) returns null. The state is a self-contained, HMAC-signed, base64-encoded token (nonce.expirationTime.signature). verifyAndDecodeState returns null if the state is malformed (wrong number of parts), signature verification fails, the expiration time is non-numeric, base64 decoding fails, or the state has expired (>10 minutes old). A null result triggers AccessException("Invalid or expired state parameter").

Source

Thrown at plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/authenticate/AuthorizationCodeHandler.java:160

        }
    }
    
    /**
     * Exchange authorization code for tokens and authenticate user.
     *
     * @param code        authorization code from IdP
     * @param state       state parameter for CSRF verification
     * @param redirectUri the redirect URI used in the authorization request
     * @return authenticated OidcUser
     * @throws AccessException if authentication fails
     */
    public OidcUser exchangeCodeForUser(String code, String state, String redirectUri)
        throws AccessException {
        try {
            // Verify and decode state (self-contained, no cache lookup needed)
            StateData stateData = verifyAndDecodeState(state);
            if (stateData == null) {
                throw new AccessException("Invalid or expired state parameter");
            }
            
            // Exchange code for tokens
            OIDCTokens tokens = exchangeCodeForTokens(code, redirectUri);
            
            // Validate ID token
            String idTokenString = tokens.getIDTokenString();
            JWTClaimsSet claims = tokenValidator.validate(idTokenString);
            
            // Verify nonce matches (protects against token replay attacks)
            String tokenNonce = (String) claims.getClaim("nonce");
            
            if (tokenNonce == null) {
                String message = "Nonce not present in ID token";
                if (config.isStrictNonceValidation()) {
                    LOGGER.error("{} - Strict validation enabled, rejecting authentication",
                        message);
                    throw new AccessException(message

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Ensure the user completes the OIDC login within the 10-minute state validity window.
  2. Confirm all Nacos cluster nodes share the same OIDC client secret (used for HMAC state signing).
  3. Verify proxies/load balancers do not strip or rewrite the state query parameter.
  4. Restart the login flow to get a fresh state if the previous one expired.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    OidcUser user = handler.exchangeCodeForUser(code, state, redirectUri);
} catch (AccessException e) {
    if ("Invalid or expired state parameter".equals(e.getMessage())) {
        // prompt user to restart the login flow for a fresh state
    }
}

Prevention

When it happens

Trigger: exchangeCodeForUser is called with a state that is tampered, truncated, expired (>10 min), from a different server instance with a different client secret (signature mismatch), or corrupted in transit. The CSRF/state validation fails and returns null.

Common situations: The user took more than 10 minutes between initiating login and the IdP callback; the Nacos server's client secret changed between the authorization request and the callback (multi-node with divergent config); the state was URL-mangled by a proxy; an attacker is replaying/altering the state.

Related errors


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