quarkusio/quarkus · error · SpiffeConnectionException
Leaf certificate must have 'digitalSignature' as key usage
Error message
Leaf certificate must have 'digitalSignature' as key usage
What it means
The leaf's KeyUsage extension must include the digitalSignature bit, since workload certificates are used to sign TLS handshakes and JWTs. If the extension exists but bit 0 is unset (or the array is empty), the validator rejects the certificate. Without digitalSignature the certificate cannot be used for the mTLS the extension establishes.
Source
Thrown at extensions/spiffe-client/runtime/src/main/java/io/quarkus/spiffe/client/runtime/internal/SpiffeValidator.java:30
private static final String SPIFFE_URI_PREFIX = "spiffe://";
private static final int URI_SAN_TYPE = 6;
private static final int MAX_SPIFFE_ID_LENGTH = 2048;
private static final int MAX_TRUST_DOMAIN_LENGTH = 255;
private SpiffeValidator() {
}
static String validateLeaf(X509Certificate leaf) throws SpiffeConnectionException {
if (leaf.getBasicConstraints() != -1) {
throw new SpiffeConnectionException("Leaf certificate must not have CA flag set to true");
}
boolean[] keyUsage = leaf.getKeyUsage();
if (keyUsage == null) {
throw new SpiffeConnectionException("Leaf certificate is missing the key usage extension");
}
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());
}View on GitHub (pinned to e1c734241f)
Solutions
- Reissue the certificate including digitalSignature in keyUsage (openssl -addext "keyUsage=digitalSignature,...").
- Use a proper test CA (e.g. cfssl or SPIRE's own tooling) that emits SPIFFE-compliant SVIDs.
- Inspect the cert: openssl x509 -noout -ext keyUsage and confirm Digital Signature is listed.
- If using a custom upstream CA, update its certificate template.
Example fix
// before -addext "keyUsage=keyEncipherment" // after -addext "keyUsage=digitalSignature,keyEncipherment"
Defensive patterns
Strategy: validation
Validate before calling
static boolean hasDigitalSignature(X509Certificate leaf) {
boolean[] ku = leaf.getKeyUsage();
return ku != null && ku.length > 0 && ku[0];
} Type guard
static boolean isSignCapableLeaf(X509Certificate cert) {
boolean[] ku = cert.getKeyUsage();
return ku != null && ku.length > 0 && ku[0];
} Try / catch
try {
SpiffeValidator.validateLeaf(leaf);
} catch (SpiffeConnectionException e) {
throw new CertificateException("Leaf cannot sign (missing digitalSignature): " + e.getMessage(), e);
} Prevention
- Always include digitalSignature in workload cert keyUsage templates
- Audit internal PKI templates reused for SPIFFE testing
- Validate locally with openssl x509 -noout -ext keyUsage before wiring tests
- Reissue certs rather than attempting client-side workarounds
When it happens
Trigger: Validation encountering a leaf whose KeyUsage is present but does not assert digitalSignature — typically from hand-generated certificates with only keyEncipherment, keyAgreement, or nonRepudiation.
Common situations: Certificates created with keyUsage=keyEncipherment only; templates from internal PKIs copied for SPIFFE tests; tooling defaults that omit digitalSignature.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Leaf certificate is missing the key usage extension
- Leaf certificate must not have 'keyCertSign' as key usage
- Signing certificate must have 'keyCertSign' as key usage: ${
- 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/ef99f7d733d2ed18.
Report an issue: GitHub.