apache/dolphinscheduler · error · ServiceException
OIDC_ID_TOKEN_AUDIENCE_INVALID
OIDC_ID_TOKEN_AUDIENCE_INVALID
Error message
OIDC_ID_TOKEN_AUDIENCE_INVALID
What it means
validateIdToken checks that the ID token's aud claim contains the configured client_id and throws ServiceException(Status.OIDC_ID_TOKEN_AUDIENCE_INVALID) when the audience list is null or does not include providerConfig.getClientId(). The audience check ensures the token was minted for this specific client, not for another relying party.
Solutions
- Verify the clientId in the DolphinScheduler OIDC provider config exactly matches the client_id registered at the OIDC provider and the one used in the authorization request.
- Decode the ID token and inspect the aud (and azp) claims to see which audience the provider is actually granting.
- Re-do the authorization-code exchange so the token is requested with the current client_id rather than reusing an old token.
- If the provider issues multi-audience tokens, ensure your client_id is listed in aud or configure the provider to include it.
Example fix
// before: client id mismatch provider.clientId=dolphinscheduler-old // after: client id matching the registration at the IdP provider.clientId=dolphinscheduler-prod
Defensive patterns
Strategy: validation
Validate before calling
// decode token and verify audience before validating
Set<String> aud = new HashSet<>(decoded.getAudience());
if (!aud.contains(config.getClientId())) {
throw new IllegalStateException("Token audience does not include configured clientId");
} Type guard
boolean audienceOk(JWTClaimsSet c, String clientId) {
try { return c.getAudience() != null && c.getAudience().contains(clientId); }
catch (java.text.ParseException e) { return false; }
} Try / catch
try {
return idTokenClaims(providerMetadata, providerConfig, idToken);
} catch (ServiceException e) {
if (String.valueOf(e.getMessage()).contains("AUDIENCE_INVALID")) {
log.error("Check clientId configuration: {} vs token aud claim", providerConfig.getClientId());
}
throw e;
} Prevention
- Keep clientId in DolphinScheduler config identical to the IdP client registration.
- After rotating credentials at the IdP, update DolphinScheduler immediately.
- Inspect aud/azp claims during IdP integration testing.
- Configure the IdP to include your client_id in aud for multi-audience setups.
When it happens
Trigger: idTokenClaims -> validateIdToken with an ID token whose aud claim omits the configured clientId, e.g. the client_id in DolphinScheduler's OIDC config differs from the one registered at the provider, or the token was issued to a different client entirely.
Common situations: client_id changed in DolphinScheduler config but the provider still issues tokens for the old client; multiple client registrations across environments; single-page apps receiving tokens with azp/multiple audiences where the expected client is only in azp; copy-pasting credentials from another application.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- OIDC_ID_TOKEN_ISSUER_INVALID
- Error parsing ID token claims
- Failed to construct OIDC redirect URI
- ID token is missing required claims
- OIDC_ID_TOKEN_EXPIRED
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/1ec5963c4ab42c55.
Report an issue: GitHub.
Appendix: source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/oidc/OidcAuthenticator.java:288
* Validate ID token and extract claims
*/
private IDTokenClaimsSet validateIdToken(OIDCProviderMetadata providerMetadata,
OidcProviderConfig providerConfig, JWT idToken) {
JWTClaimsSet claimsSet;
try {
claimsSet = idToken.getJWTClaimsSet();
} catch (java.text.ParseException e) {
throw new ServiceException("Error parsing ID token claims", e);
}
String issuer = claimsSet.getIssuer();
if (issuer == null || !issuer.equals(providerMetadata.getIssuer().getValue())) {
throw new ServiceException(Status.OIDC_ID_TOKEN_ISSUER_INVALID);
}
List<String> audiences = claimsSet.getAudience();
if (audiences == null || !audiences.contains(providerConfig.getClientId())) {
throw new ServiceException(Status.OIDC_ID_TOKEN_AUDIENCE_INVALID);
}
Date expirationTime = claimsSet.getExpirationTime();
if (expirationTime == null || expirationTime.before(new Date())) {
throw new ServiceException(Status.OIDC_ID_TOKEN_EXPIRED);
}
try {
return new IDTokenClaimsSet(claimsSet);
} catch (ParseException e) {
log.error("Failed to parse ID token claims, required claims may be missing.", e);
throw new ServiceException("ID token is missing required claims", e);
}
}
/**
* Get user info from UserInfo endpoint
*/View on GitHub (pinned to 02eac45a1b)