prestodb/presto · error · ChallengeFailedException

Cannot validate tokens

Error message

Cannot validate tokens

What it means

After fetching OIDC tokens, validateTokens verifies the ID token signature and claims with Nimbus JOSE+JWT and optionally the access token hash; any BadJOSEException, JOSEException, or InvalidHashException is wrapped in ChallengeFailedException('Cannot validate tokens').

Source

Thrown at presto-main/src/main/java/com/facebook/presto/server/security/oauth2/NimbusOAuth2Client.java:419

            }
        }

        private void validateTokens(OIDCTokens tokens, Optional<String> nonce)
                throws ChallengeFailedException
        {
            try {
                IDTokenClaimsSet idToken = idTokenValidator.validate(
                        tokens.getIDToken(),
                        nonce.map(this::hashNonce)
                                .map(Nonce::new)
                                .orElse(null));
                AccessTokenHash accessTokenHash = idToken.getAccessTokenHash();
                if (accessTokenHash != null) {
                    AccessTokenValidator.validate(tokens.getAccessToken(), ((JWSHeader) tokens.getIDToken().getHeader()).getAlgorithm(), accessTokenHash);
                }
            }
            catch (BadJOSEException | JOSEException | InvalidHashException e) {
                throw new ChallengeFailedException("Cannot validate tokens", e);
            }
        }

        private void validateTokens(OIDCTokens tokens)
                throws ChallengeFailedException
        {
            validateTokens(tokens, Optional.empty());
        }

        private String hashNonce(String nonce)
        {
            return sha256()
                    .hashString(nonce, UTF_8)
                    .toString();
        }
    }

    private <T extends AccessTokenResponse> T getTokenResponse(String code, URI callbackUri, NimbusAirliftHttpClient.Parser<T> parser)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Verify oauth2.issuer-url, oauth2.principal-field and client id match the IdP exactly
  2. Refresh/restart so the JWKS is re-fetched after an IdP key rotation
  3. Check clock skew (NTP) on the coordinator against IdP token timestamps
  4. Confirm the IdP signs ID tokens with an algorithm the Nimbus processor accepts (typically RS256) and at_hash matches the access token

Example fix

// before
// issuer-url = https://old-idp.example.com (rotated)
// after
// issuer-url = https://new-idp.example.com ; restart coordinator to reload JWKS
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: decode ID token JWT, verify iss == configured issuer-url and exp > now before calling validateTokens

Type guard

boolean claimsMatchConfig(com.nimbusds.jwt.JWTClaimsSet claims, java.net.URI issuer, String clientId) { return issuer.toString().equals(claims.getIssuer()) && java.util.Arrays.asList(claims.getAudience()).contains(clientId); }

Try / catch

try { client.getOAuth2Response(code, callbackUri, nonce); } catch (ChallengeFailedException e) { if (e.getCause() instanceof com.nimbusds.jose.JOSEException) { refreshJwksAndRetry(); } throw e; }

Prevention

When it happens

Trigger: ID token signed by an untrusted/unconfigured key (JWKS mismatch), token expired or wrong issuer/audience, at_hash mismatch between access token and ID token, or malformed JWT from the IdP.

Common situations: IdP rotated signing keys and the coordinator cached stale JWKS, clock skew making tokens appear expired, wrong issuer-url or principal-field config, IdP updated to a signing algorithm the local configuration rejects, RS256 vs HS256 surprises.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/fe3b2bae31ac1319. Report an issue: GitHub.