alibaba/nacos · error · AccessException

Token audience validation failed

Error message

Token audience validation failed

What it means

Thrown by validateClaims during strict audience validation: client-id is configured, the token's 'aud' does not contain it, and the 'azp' (authorized party) claim also does not match. Only fires when strict-audience-validation=true (the default).

Source

Thrown at plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/token/JwtTokenValidator.java:230

            throw new AccessException("Token is not yet valid");
        }
        
        // Validate audience (if client ID is configured)
        String clientId = config.getClientId();
        if (StringUtils.isNotBlank(clientId)) {
            List<String> audience = claims.getAudience();
            if (audience != null && !audience.isEmpty() && !audience.contains(clientId)) {
                // Check if 'azp' (authorized party) matches
                String azp = (String) claims.getClaim("azp");
                if (!clientId.equals(azp)) {
                    String message = String.format(
                        "Token audience mismatch. Expected: %s, Got: %s, azp: %s",
                        clientId, audience, azp);
                    
                    if (config.isStrictAudienceValidation()) {
                        LOGGER.error("{} - Strict validation enabled, rejecting token. "
                            + "This token may be intended for a different client.", message);
                        throw new AccessException("Token audience validation failed");
                    } else {
                        LOGGER.warn("{} - Strict validation disabled, accepting token. "
                            + "Set 'nacos.plugin.auth.oidc.strict-audience-validation=true' for better security.",
                            message);
                    }
                }
            }
        }
        
        // Validate issuer
        String issuer = claims.getIssuer();
        String expectedIssuer = config.getIssuerUri();
        if (StringUtils.isNotBlank(expectedIssuer) && !expectedIssuer.equals(issuer)) {
            // Handle trailing slash difference
            String normalizedExpected = expectedIssuer.endsWith("/")
                ? expectedIssuer.substring(0, expectedIssuer.length() - 1)
                : expectedIssuer;
            String normalizedIssuer = issuer != null && issuer.endsWith("/")

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Set client-id to the exact value the IdP mints into aud/azp for the Nacos client.
  2. Verify the IdP client configuration includes Nacos in the allowed audiences.
  3. As a temporary/less-secure measure, set strict-audience-validation=false (the token will be accepted with only a WARN log).
  4. Decode the token and confirm the actual aud and azp values, then align client-id.
  5. Inspect the ERROR log 'Token audience mismatch. Expected: ... Got: ... azp: ...' for the exact mismatch.

Example fix

# before
nacos.plugin.auth.oidc.client-id=nacos-wrong
nacos.plugin.auth.oidc.strict-audience-validation=true

# after: align client-id with token aud/azp
nacos.plugin.auth.oidc.client-id=nacos-client
# (or, less secure) nacos.plugin.auth.oidc.strict-audience-validation=false
Defensive patterns

Strategy: validation

Validate before calling

JWTClaimsSet preview = JWTClaimsSet.parse(new String(Base64.getUrlDecoder().decode(token.split("\\.")[1])));
String clientId = config.getClientId();
List<String> aud = preview.getAudience();
String azp = (String) preview.getClaim("azp");
boolean ok = aud == null || aud.isEmpty() || aud.contains(clientId) || clientId.equals(azp);
if (!ok && config.isStrictAudienceValidation()) {
    // fix client-id or disable strict mode before calling validate()
}

Try / catch

try {
    validator.validate(token);
} catch (AccessException e) {
    if ("Token audience validation failed".equals(e.getMessage())) {
        // 403 wrong_audience; align client-id with token aud/azp
    }
    throw e;
}

Prevention

When it happens

Trigger: config.getClientId() is non-blank, claims.getAudience() is non-empty and excludes clientId, claims.getClaim('azp') != clientId, and config.isStrictAudienceValidation() is true.

Common situations: client-id is misconfigured (typo, wrong IdP client); the token was minted for a different audience/client; multi-audience token without the Nacos client in it; copying a client-id from one IdP environment to another.

Related errors


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