quarkusio/quarkus · error · org.jose4j.keys.resolvers.UnresolvableKeyException

JWK with the SHA256 certificate thumbprint '%s' is not avail

Error message

JWK with the SHA256 certificate thumbprint '%s' is not available

What it means

Thrown by OidcProvider's JsonWebKeyResolver.resolveKey when the token has no usable 'kid' but declares an 'x5t#S256' (SHA-256 X.509 certificate thumbprint) header, and no JWK in the key set matches that thumbprint. Since only 'x5tS256' was set, the resolver must find the exact key and cannot fall back, so it fails fast with UnresolvableKeyException.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/OidcProvider.java:565

            // Try 'kid' first
            String kid = jws.getKeyIdHeaderValue();
            if (kid != null) {
                key = getKeyWithId(kid);
                if (key == null) {
                    // if `kid` was set then the key must exist
                    throw new UnresolvableKeyException(String.format("JWK with kid '%s' is not available", kid));
                }
            }

            String thumbprint = null;
            if (key == null) {
                thumbprint = jws.getHeader(HeaderParameterNames.X509_CERTIFICATE_SHA256_THUMBPRINT);
                if (thumbprint != null) {
                    key = getKeyWithS256Thumbprint(thumbprint);
                    if (key == null) {
                        // if only `x5tS256` was set then the key must exist
                        throw new UnresolvableKeyException(
                                String.format("JWK with the SHA256 certificate thumbprint '%s' is not available", thumbprint));
                    }
                }
            }

            if (key == null) {
                thumbprint = jws.getHeader(HeaderParameterNames.X509_CERTIFICATE_THUMBPRINT);
                if (thumbprint != null) {
                    key = getKeyWithThumbprint(thumbprint);
                    if (key == null) {
                        // if only `x5t` was set then the key must exist
                        throw new UnresolvableKeyException(
                                String.format("JWK with the certificate thumbprint '%s' is not available", thumbprint));
                    }
                }
            }

            if (key == null && kid == null && thumbprint == null) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the JWK set contains an x5c certificate whose SHA-256 thumbprint matches the token header; ask the issuer to publish full certificate chains
  2. Check the token really came from the configured tenant's JWKS endpoint
  3. If the token has neither matching kid nor thumbprint, configure the expected signing key statically (quarkus.oidc.token.public-key / certificate-chain)
  4. Refresh JWKS in case keys rotated since the cache was filled

Example fix

// token x5tS256: 'AbCd...' not matched because JWKS publishes only n/e
// after: issuer publishes x5c, or app pins the key:
quarkus.oidc.token.certificate-chain=... // pin the leaf cert
Defensive patterns

Strategy: fallback

Validate before calling

// check token header has x5t#S256 and JWKS exposes x5c certs before verifying
if (header.getX509CertSHA256Thumbprint() != null && jwksKeys.stream().noneMatch(k -> k.getX509CertificateChain() != null)) {
    throw new IllegalStateException("Token uses x5t#S256 but JWKS has no x5c certificates");
}

Try / catch

try {
    return validate(token);
} catch (AuthenticationFailedException e) {
    if (String.valueOf(e.getCause()).contains("SHA256 certificate thumbprint")) {
        return refreshJwksAndRetry(token);
    }
    throw e;
}

Prevention

When it happens

Trigger: Verifying a JWT whose header contains 'x5t#S256' (and no 'kid') while getKeyWithS256Thumbprint(thumbprint) returns null against the tenant's key set.

Common situations: Token issuer embeds its cert thumbprint in the header but the JWKS entry lacks the x5c chain needed to compute S256 thumbprints (only RSA modulus/exponent exposed); x509 thumbprint algorithm mismatch between issuer and JWKS; tokens issued by a different provider than configured.

Understand the failure class

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/1f95857d8f8b68d8. Report an issue: GitHub.