{"record":{"id":"7f07f934ed9fc708","repo":"quarkusio/quarkus","slug":"signing-certificate-must-have-ca-flag-set-to-true","errorCode":null,"errorMessage":"Signing certificate must have CA flag set to true: ${subjectX500Principal}","messagePattern":"Signing certificate must have CA flag set to true: (.+?)","errorType":"exception","errorClass":"SpiffeConnectionException","httpStatus":null,"severity":"error","filePath":"extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java","lineNumber":46,"sourceCode":"        }\n        if (keyUsage.length < 1 || !keyUsage[0]) {\n            throw new SpiffeConnectionException(\"Leaf certificate must have 'digitalSignature' as key usage\");\n        }\n        if (keyUsage.length > 5 && keyUsage[5]) {\n            throw new SpiffeConnectionException(\"Leaf certificate must not have 'keyCertSign' as key usage\");\n        }\n        if (keyUsage.length > 6 && keyUsage[6]) {\n            throw new SpiffeConnectionException(\"Leaf certificate must not have 'cRLSign' as key usage\");\n        }\n\n        return extractAndValidateUriSan(leaf);\n    }\n\n    // X.509-SVID 3.2 SHOULD: signing cert SHOULD itself be an SVID (not enforced — upstream CA may not be SPIFFE-aware)\n    // X.509-SVID 3.2 SHOULD: signing cert SHOULD reside in the trust domain of leaf SVIDs it issues (not enforced — cross-domain signing is allowed)\n    static void validateIntermediate(X509Certificate cert) throws SpiffeConnectionException {\n        if (cert.getBasicConstraints() < 0) {\n            throw new SpiffeConnectionException(\n                    \"Signing certificate must have CA flag set to true: \" + cert.getSubjectX500Principal());\n        }\n        boolean[] keyUsage = cert.getKeyUsage();\n        if (keyUsage == null || keyUsage.length <= 5 || !keyUsage[5]) {\n            throw new SpiffeConnectionException(\n                    \"Signing certificate must have 'keyCertSign' as key usage: \" + cert.getSubjectX500Principal());\n        }\n        // X.509-SVID 3.2 MUST: if signing cert has a SPIFFE ID, it must not have a path component\n        String uriSan = extractOptionalUriSan(cert);\n        if (uriSan != null && uriSan.startsWith(SPIFFE_URI_PREFIX)) {\n            URI uri = URI.create(uriSan);\n            String path = uri.getPath();\n            if (path != null && !path.isEmpty() && !\"/\".equals(path)) {\n                throw new SpiffeConnectionException(\n                        \"Signing certificate SPIFFE ID must not have a path component: \" + uriSan);\n            }\n        }\n    }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java#L28-L64","documentation":"Signing (CA) certificates in the SVID chain must have the BasicConstraints CA flag set to true. Quarkus SPIFFE client validates this in SpiffeValidator.validateIntermediate; if getBasicConstraints() returns -1 (not a CA), the chain cannot be trusted to sign leaf SVIDs and a SpiffeConnectionException is thrown.","triggerScenarios":"Presenting a trust bundle / intermediate chain where one of the signing certificates lacks the BasicConstraints extension or has cA=false; detected during intermediate validation after leaf validation.","commonSituations":"The trust bundle was assembled with a leaf or end-entity certificate mistakenly included as an intermediate; a self-signed server cert was pasted into the trust store; CA cert was regenerated without the CA:TRUE constraint.","solutions":["Replace the offending certificate in the trust bundle with a genuine CA certificate (BasicConstraints critical, cA=TRUE).","Regenerate the signing certificate with basicConstraints=critical,CA:TRUE.","Verify trust-bundle contents with `openssl x509 -text` and remove any non-CA certs."],"exampleFix":"// before (openssl ca config for signing cert)\nbasicConstraints = CA:false\n// after\nbasicConstraints = critical, CA:true","handlingStrategy":"validation","validationCode":"if (cert.getBasicConstraints() < 0) {\n    throw new IllegalArgumentException(\"Not a CA certificate: \" + cert.getSubjectX500Principal());\n}","typeGuard":null,"tryCatchPattern":"try {\n    connection.establish();\n} catch (SpiffeConnectionException e) {\n    if (e.getMessage().contains(\"CA flag\")) {\n        log.error(\"Trust bundle contains a non-CA certificate\", e);\n    }\n    throw e;\n}","preventionTips":["Verify every trust-bundle cert has BasicConstraints CA:TRUE before distributing it","Never paste leaf/server certificates into trust stores","Regenerate CA certs with basicConstraints=critical,CA:true"],"tags":["x509","certificate-chain","spiffe","trust-bundle"],"backgroundTag":"certificate-key-usage-violation","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"}