{"record":{"id":"e897abdc091a5d1f","repo":"quarkusio/quarkus","slug":"thumprint-of-the-leaf-chain-certificate-is-invalid","errorCode":null,"errorMessage":"Thumprint of the leaf chain certificate is invalid","messagePattern":"Thumprint of the leaf chain certificate is invalid","errorType":"exception","errorClass":"UnresolvableKeyException","httpStatus":401,"severity":"error","filePath":"extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CertChainPublicKeyResolver.java","lineNumber":98,"sourceCode":"                }\n            }\n\n            // Finally, check the leaf certificate if required\n            if (expectedLeafCertificateName.isPresent()) {\n                // Compare the leaf certificate common name against the configured value\n                String leafCertificateName = HttpSecurityUtils.getCommonName(chain.get(0).getSubjectX500Principal());\n                if (!expectedLeafCertificateName.get().equals(leafCertificateName)) {\n                    LOG.errorf(\"Wrong leaf certificate common name: %s\", leafCertificateName);\n                    throw new UnresolvableKeyException(\"Wrong leaf certificate common name\");\n                }\n            } else if (certificateValidators.isEmpty()) {\n                // No custom validators are registered and no leaf certificate CN is configured\n                // Check that the truststore contains a leaf certificate thumbprint\n                LOG.debug(\"Checking a thumbprint of the leaf chain certificate\");\n                String thumbprint = TrustStoreUtils.calculateThumprint(chain.get(0));\n                if (!thumbprints.contains(thumbprint)) {\n                    LOG.error(\"Thumprint of the leaf chain certificate is invalid\");\n                    throw new UnresolvableKeyException(\"Thumprint of the leaf chain certificate is invalid\");\n                }\n            }\n\n            return chain.get(0).getPublicKey();\n        } catch (UnresolvableKeyException ex) {\n            throw ex;\n        } catch (Exception ex) {\n            throw new UnresolvableKeyException(\"Invalid certificate chain\", ex);\n        }\n    }\n}\n","sourceCodeStart":80,"sourceCodeEnd":110,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/CertChainPublicKeyResolver.java#L80-L110","documentation":"When neither a leaf certificate CN is configured nor custom TokenCertificateValidators are registered, the resolver falls back to checking that the thumbprint of the leaf (first) certificate in the token's x5c chain is present in the truststore. If not, the leaf itself is untrusted and UnresolvableKeyException is thrown.","triggerScenarios":"resolveKey() runs with expectedLeafCertificateName empty and certificateValidators empty, and TrustStoreUtils.calculateThumprint(chain.get(0)) is not in the set of thumbprints from the configured truststore.","commonSituations":"Issuer rotated its leaf/signing certificate but only the root was imported; truststore contains only the CA certificate while tokens embed a specific leaf certificate; tenant is receiving tokens signed by a sibling issuer's leaf.","solutions":["Import the current leaf certificate of the token issuer into the truststore (keytool -importcert) and restart.","Or import the root CA only and configure quarkus.oidc.certificate-chain.leaf-certificate-name so leaf verification goes by CN instead of thumbprint.","Or register a TokenCertificateValidator bean to perform custom leaf validation.","Re-export tokens so they carry the certificate chain matching the truststore contents."],"exampleFix":"keytool -importcert -alias issuer-leaf -file issuer-leaf.crt -keystore truststore.p12 -storetype PKCS12","handlingStrategy":"validation","validationCode":"Set<String> trusted = TrustStoreUtils.getTrustedCertificateThumbprints(trustStoreFile, password, alias, fileType);\nString leafTp = TrustStoreUtils.calculateThumprint(chain.get(0));\nif (!trusted.contains(leafTp)) {\n    log.warn(\"Leaf certificate thumbprint not in truststore; import leaf cert or configure leaf-certificate-name / a validator\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return jwtVerify(token);\n} catch (UnresolvableKeyException e) {\n    if (\"Thumprint of the leaf chain certificate is invalid\".equals(e.getMessage())) {\n        log.error(\"Import the issuer's current leaf certificate into the truststore\");\n    }\n    throw e;\n}","preventionTips":["Import both the leaf and root certificates of the issuer into the truststore.","After issuer certificate rotation, re-import the new leaf before old tokens expire.","Automate truststore regeneration from the issuer's JWKS/x5c in deployment pipelines."],"tags":["oidc","certificate-chain","thumbprint","leaf-certificate"],"backgroundTag":"untrusted-certificate-chain","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}