apache/dolphinscheduler · error · ServiceException
OIDC_ID_TOKEN_ISSUER_INVALID
OIDC_ID_TOKEN_ISSUER_INVALID
Error message
OIDC_ID_TOKEN_ISSUER_INVALID
What it means
validateIdToken compares the ID token's iss claim against the issuer published in the OIDC provider metadata and throws ServiceException(Status.OIDC_ID_TOKEN_ISSUER_INVALID) when the claim is missing or does not match exactly. Per the OIDC spec, the issuer must match the value discovered from the provider's .well-known/openid-configuration; any mismatch means the token was not issued by the configured provider.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/oidc/OidcAuthenticator.java:283
throw new ServiceException("Failed to construct OIDC redirect URI", e);
}
}
/**
* 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);
}View on GitHub (pinned to 02eac45a1b)
Solutions
- Compare the configured issuer URL against the token's iss claim byte-for-byte, watching for trailing slashes, http vs https, port numbers, and path segments; fix the configured OIDC issuer URL to match exactly.
- Verify the provider metadata was fetched from the same environment that issued the token (staging vs production).
- If the provider sits behind a proxy, ensure the proxy forwards the issuer the provider itself signs with, or update the configured value accordingly.
- Decode the token and inspect the iss claim directly to see what value the provider is actually using.
Example fix
// before: config issuer with trailing slash doesn't match token iss provider.issuer=https://sso.example.com/ // after: issuer must exactly equal the iss claim provider.issuer=https://sso.example.com
Defensive patterns
Strategy: validation
Validate before calling
// before login, assert configured issuer matches provider metadata assert config.getIssuerUrl().equals(providerMetadata.getIssuer().getValue()); // decode the incoming token and compare claims decoded.iss == config.getIssuerUrl() // exact string equality, no trailing slash
Type guard
boolean issuerMatches(String iss, OIDCProviderMetadata md) {
return iss != null && md.getIssuer() != null && iss.equals(md.getIssuer().getValue());
} Try / catch
try {
return oidcAuthenticator.idTokenClaims(providerMetadata, providerConfig, idToken);
} catch (ServiceException e) {
log.warn("OIDC validation failed: {}", e.getMessage());
return redirectToIdentityProvider(); // restart login
} Prevention
- Copy the issuer URL exactly from the IdP's .well-known/openid-configuration.
- Watch for trailing slashes, http/https, ports, and reverse-proxy host differences.
- Use distinct configs per environment (staging vs production).
- Add an integration test asserting the token's iss equals the configured value.
When it happens
Trigger: idTokenClaims -> validateIdToken with an ID token whose iss claim is null, differs by trailing slash/scheme/port, or points to a different environment's issuer than the one configured in providerConfig/OIDCProviderMetadata.
Common situations: Configured issuer URL missing or having a trailing slash while the provider omits it (or vice versa); token issued by a staging provider while DolphinScheduler is pointed at production metadata; provider behind a reverse proxy exposing a different external issuer; http vs https mismatch.
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_AUDIENCE_INVALID
- Failed to construct OIDC redirect URI
- Error parsing ID token claims
- OIDC_ID_TOKEN_EXPIRED
- ID token is missing required claims
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/cca5e2ec26f35895.
Report an issue: GitHub.