quarkusio/quarkus · error · SpiffeConnectionException
Signing certificate must have CA flag set to true: ${subject
Error message
Signing certificate must have CA flag set to true: ${subjectX500Principal} What it means
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.
Source
Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:46
}
if (keyUsage.length < 1 || !keyUsage[0]) {
throw new SpiffeConnectionException("Leaf certificate must have 'digitalSignature' as key usage");
}
if (keyUsage.length > 5 && keyUsage[5]) {
throw new SpiffeConnectionException("Leaf certificate must not have 'keyCertSign' as key usage");
}
if (keyUsage.length > 6 && keyUsage[6]) {
throw new SpiffeConnectionException("Leaf certificate must not have 'cRLSign' as key usage");
}
return extractAndValidateUriSan(leaf);
}
// X.509-SVID 3.2 SHOULD: signing cert SHOULD itself be an SVID (not enforced — upstream CA may not be SPIFFE-aware)
// 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)
static void validateIntermediate(X509Certificate cert) throws SpiffeConnectionException {
if (cert.getBasicConstraints() < 0) {
throw new SpiffeConnectionException(
"Signing certificate must have CA flag set to true: " + cert.getSubjectX500Principal());
}
boolean[] keyUsage = cert.getKeyUsage();
if (keyUsage == null || keyUsage.length <= 5 || !keyUsage[5]) {
throw new SpiffeConnectionException(
"Signing certificate must have 'keyCertSign' as key usage: " + cert.getSubjectX500Principal());
}
// X.509-SVID 3.2 MUST: if signing cert has a SPIFFE ID, it must not have a path component
String uriSan = extractOptionalUriSan(cert);
if (uriSan != null && uriSan.startsWith(SPIFFE_URI_PREFIX)) {
URI uri = URI.create(uriSan);
String path = uri.getPath();
if (path != null && !path.isEmpty() && !"/".equals(path)) {
throw new SpiffeConnectionException(
"Signing certificate SPIFFE ID must not have a path component: " + uriSan);
}
}
}View on GitHub (pinned to e1c734241f)
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.
Example fix
// before (openssl ca config for signing cert) basicConstraints = CA:false // after basicConstraints = critical, CA:true
Defensive patterns
Strategy: validation
Validate before calling
if (cert.getBasicConstraints() < 0) {
throw new IllegalArgumentException("Not a CA certificate: " + cert.getSubjectX500Principal());
} Try / catch
try {
connection.establish();
} catch (SpiffeConnectionException e) {
if (e.getMessage().contains("CA flag")) {
log.error("Trust bundle contains a non-CA certificate", e);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Signing certificate must have 'keyCertSign' as key usage: ${
- Signing certificate SPIFFE ID must not have a path component
- Invalid certificate chain
- X.509-SVID response from SPIRE agent contains no SVIDs
- X.509-SVID response from SPIRE agent has empty certificate c
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/7f07f934ed9fc708.
Report an issue: GitHub.