apache/dolphinscheduler · error · ServiceException

Error parsing ID token claims

Error message

Error parsing ID token claims

What it means

OidcAuthenticator.validateIdToken wraps java.text.ParseException thrown by idToken.getJWTClaimsSet() into a ServiceException with the message "Error parsing ID token claims". This happens when the ID token's payload is not a valid JWT claims JSON structure, so the Nimbus JWT library cannot extract the claims set. It is thrown before any issuer/audience/expiry validation takes place.

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/oidc/OidcAuthenticator.java:278

            }

            return ((OIDCTokenResponse) tokenResponse).getOIDCTokens();
        } catch (java.net.URISyntaxException e) {
            log.error("Invalid redirect URI configured for OIDC provider: {}", providerId, e);
            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 {

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Log the raw ID token (never to production logs) and decode it at jwt.io to confirm it is a well-formed three-segment JWT with a JSON payload.
  2. Verify the OIDC provider is actually issuing JWT ID tokens (response_type/id_token_issued behavior) and that you are reading the id_token field, not an access token.
  3. Check for middleware or proxies that truncate or rewrite the token between provider and DolphinScheduler.
  4. If the token is truncated client-side, fix the callback handling that forwards the token to the authenticator.

Example fix

// before: blindly passing whatever came back from the provider
JWT idToken = ...; // could be opaque or malformed
validateIdToken(providerMetadata, providerConfig, idToken);

// after: sanity-check the token shape before validating
private boolean isWellFormedJwt(String token) {
    return token != null && token.chars().filter(c -> c == '.').count() == 2;
}
if (!isWellFormedJwt(rawIdToken)) {
    throw new ServiceException("Provider returned a malformed ID token");
}
Defensive patterns

Strategy: try-catch

Validate before calling

private static boolean looksLikeJwt(String t) {
    if (t == null) return false;
    String[] parts = t.split("\\.");
    if (parts.length != 3) return false;
    try { new String(java.util.Base64.getUrlDecoder().decode(parts[1]), java.nio.charset.StandardCharsets.UTF_8); return true; }
    catch (IllegalArgumentException e) { return false; }
}

Type guard

if (!(token instanceof com.nimbusds.jose.JWTParser.ParsedJWT) && !looksLikeJwt(rawToken)) { skip validation; report malformed token }

Try / catch

try {
    claimsSet = idToken.getJWTClaimsSet();
} catch (java.text.ParseException e) {
    log.error("Malformed ID token payload", e);
    return redirectLogin("invalid_token");
}

Prevention

When it happens

Trigger: Calling idTokenClaims -> validateIdToken with an ID token whose payload segment is malformed or not valid JSON (e.g. an opaque token, a truncated token, or a token whose payload was re-encoded incorrectly) so getJWTClaimsSet() throws java.text.ParseException.

Common situations: Misconfigured OIDC provider returning an opaque or non-JWT response token instead of a signed JWT; manual string manipulation of tokens in tests; proxy/gateway truncating or rewriting the token; copying a token with whitespace or missing segments.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/e23670d0e08fe74b. Report an issue: GitHub.