alibaba/nacos · error · AccessException

Authentication failed: {errorMessage}

Error message

Authentication failed: {errorMessage}

What it means

Thrown by AuthorizationCodeHandler.exchangeCodeForUser as the catch-all for any non-AccessException during the code-for-user exchange flow (state decode, token exchange, ID-token validation, claim mapping). The handler wraps the original message into AccessException("Authentication failed: " + e.getMessage()) and logs the full stack trace at ERROR. AccessException instances are rethrown unchanged before this catch.

Source

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

            } else if (!stateData.nonce.equals(tokenNonce)) {
                String message = String.format("Nonce mismatch: expected %s, got %s",
                    stateData.nonce, tokenNonce);
                LOGGER.error("{} - Possible token replay attack detected", message);
                throw new AccessException(message);
            }
            
            // Map claims to user
            OidcUser user = userMapper.mapToUser(claims);
            user.setToken(tokens.getAccessToken().getValue());
            
            LOGGER.info("User authenticated via authorization code: {}", user.getUsername());
            return user;
            
        } catch (AccessException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("Failed to exchange code for tokens", e);
            throw new AccessException("Authentication failed: " + e.getMessage());
        }
    }
    
    /**
     * Exchange authorization code for OIDC tokens.
     *
     * @param code        authorization code
     * @param redirectUri redirect URI
     * @return OIDC tokens
     * @throws Exception if exchange fails
     */
    private OIDCTokens exchangeCodeForTokens(String code, String redirectUri) throws Exception {
        String tokenEndpoint = metadataProvider.getMetadata().getTokenEndpoint();
        if (StringUtils.isBlank(tokenEndpoint)) {
            throw new AccessException("Token endpoint not configured");
        }
        
        // Build token request

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Read the server log for 'Failed to exchange code for tokens' — it logs the original exception with the true root cause.
  2. If it's a token-endpoint network error, verify the IdP token endpoint URL and network reachability.
  3. If it's a signature validation error, confirm the JWKS/issuer config matches the IdP.
  4. Fix the specific underlying exception identified in the stack trace.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    OidcUser user = handler.exchangeCodeForUser(code, state, redirectUri);
} catch (AccessException e) {
    // AccessException is the base; check server log 'Failed to exchange code for tokens'
    // for the original exception to find the true root cause
}

Prevention

When it happens

Trigger: Any unexpected Exception in exchangeCodeForUser outside the explicit AccessException paths: token endpoint HTTP call fails, ID-token signature validation throws, userMapper.mapToUser throws, or tokens.getAccessToken() returns null causing an NPE.

Common situations: The IdP token endpoint is unreachable or returns an error not caught by the explicit handling; the JWT validator rejects the ID token signature (JWK mismatch); the access token is null; a claim-mapping misconfiguration throws during user creation.

Understand the failure class

Related errors


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