quarkusio/quarkus · error · UnresolvableKeyException

Invalid certificate chain

Error message

Invalid certificate chain

What it means

This is the catch-all wrapping error in CertChainPublicKeyResolver.resolveKey: any exception during certificate chain processing that is not already an UnresolvableKeyException (e.g. CertificateExpiredException, signature verification failure, malformed x5c data, crypto errors) is wrapped into an UnresolvableKeyException with message 'Invalid certificate chain' and the original exception as cause.

Source

Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CertChainPublicKeyResolver.java:106

                    LOG.errorf("Wrong leaf certificate common name: %s", leafCertificateName);
                    throw new UnresolvableKeyException("Wrong leaf certificate common name");
                }
            } else if (certificateValidators.isEmpty()) {
                // No custom validators are registered and no leaf certificate CN is configured
                // Check that the truststore contains a leaf certificate thumbprint
                LOG.debug("Checking a thumbprint of the leaf chain certificate");
                String thumbprint = TrustStoreUtils.calculateThumprint(chain.get(0));
                if (!thumbprints.contains(thumbprint)) {
                    LOG.error("Thumprint of the leaf chain certificate is invalid");
                    throw new UnresolvableKeyException("Thumprint of the leaf chain certificate is invalid");
                }
            }

            return chain.get(0).getPublicKey();
        } catch (UnresolvableKeyException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new UnresolvableKeyException("Invalid certificate chain", ex);
        }
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Inspect the exception cause in the application log to see the underlying failure (expired cert, signature mismatch, etc.).
  2. Renew the expired certificate on the token issuer side and redeploy/restart the issuer.
  3. Fix clock skew on the Quarkus host (NTP sync) if certificates are rejected as expired/not-yet-valid.
  4. Ensure the issuer embeds a well-formed, complete x5c chain (leaf plus intermediates plus root).
Defensive patterns

Strategy: try-catch

Validate before calling

for (X509Certificate cert : chain) {
    cert.checkValidity(); // throws CertificateExpiredException / CertificateNotYetValidException early
}

Try / catch

try {
    return jwtVerify(token);
} catch (UnresolvableKeyException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid certificate chain")) {
        log.errorf("Chain processing failed: %s", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: resolveKey() throws from CertificateHelper.checkValidity(chain, null) (expired/not-yet-valid cert, path validation failure), root.verify(root.getPublicKey()) failing for a single-cert chain, or thumbprint calculation errors.

Common situations: Expired or not-yet-valid certificates in the token's x5c chain; system clock skew on the Quarkus host; corrupted or mis-encoded x5c header; self-signed single certificate whose self-signature does not verify.

Understand the failure class

Related errors


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