apereo/cas · warning
Configuration specifies checkKeyUsage but keyUsage…
Error message
Configuration specifies checkKeyUsage but keyUsage extension not found in certificate.
What it means
The handler is configured to check the keyUsage extension (checkKeyUsage=true) but the presented certificate contains no keyUsage extension at all. isValidKeyUsage logs this warning and returns !requireKeyUsage, meaning the certificate is rejected only when keyUsage is also marked as required; otherwise validation continues despite the missing extension.
Solutions
- If your certificates intentionally lack keyUsage, either disable the check (set check-key-usage=false) or keep require-key-usage=false so missing extensions are tolerated.
- Re-issue the client certificate with a template/profile that includes the keyUsage extension (best long-term fix).
- If the extension must exist and be valid, leave require-key-usage=true and have your CA issue certificates with keyUsage; certificates without it will be rejected as expected.
- Inspect the failing certificate (openssl x509 -text) to confirm keyUsage is truly absent before changing configuration.
Example fix
// before cas.authn.x509.check-key-usage=true cas.authn.x509.require-key-usage=true // after (certificates without keyUsage are accepted) cas.authn.x509.check-key-usage=true cas.authn.x509.require-key-usage=false
Defensive patterns
Strategy: validation
Validate before calling
// Check the certificate before validation:
val keyUsage = certificate.getKeyUsage();
if (keyUsage == null && requireKeyUsage) {
logger.warn("Certificate {} lacks keyUsage but it is required; will be rejected", certificate.getSerialNumber());
} Try / catch
try {
handler.authenticate(x509Credential);
} catch (FailedLoginException e) {
if (certificate.getKeyUsage() == null) {
logger.warn("Certificate has no keyUsage extension; relax require-key-usage or reissue cert");
}
throw e;
} Prevention
- Audit your CA's certificate templates to confirm keyUsage is present before enabling checkKeyUsage.
- Prefer requiring keyUsage=true only when you control certificate issuance.
- Inspect client certificates with openssl x509 -text when diagnosing X.509 auth failures.
- Document the intended combination of check-key-usage and require-key-usage for operators.
When it happens
Trigger: validate() calls isValidKeyUsage() during certificate validation; certificate.getKeyUsage() returns null because the certificate was issued without a keyUsage extension while cas.authn.x509 check-key-usage is enabled in configuration.
Common situations: CA issues certificates without the keyUsage extension (common with some client/certificate templates); operator enables checkKeyUsage based on documentation without knowing their CA's certificate profiles; migration between CAs with different certificate templates.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Unable to accept certificate
- No Certificates provided
- Public and private keys do not match
- Configuration element indicated an entityCertificate, but…
- Could not decode provided Entity Certificate file
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/3b23d7d7a0d2dc5c.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-x509-core/src/main/java/org/apereo/cas/adaptors/x509/authentication/handler/support/X509CredentialsAuthenticationHandler.java:272
throw new FailedLoginException(msg);
}
}
}
/**
* Checks if is valid key usage. <p>
* KeyUsage ::= BIT STRING { digitalSignature (0), nonRepudiation (1),
* keyEncipherment (2), dataEncipherment (3), keyAgreement (4),
* keyCertSign (5), cRLSign (6), encipherOnly (7), decipherOnly (8) }
*
* @param certificate the certificate
* @return true, if valid key usage
*/
private boolean isValidKeyUsage(final X509Certificate certificate) {
LOGGER.debug("Checking certificate keyUsage extension");
val keyUsage = certificate.getKeyUsage();
if (keyUsage == null) {
LOGGER.warn("Configuration specifies checkKeyUsage but keyUsage extension not found in certificate.");
return !this.requireKeyUsage;
}
val func = FunctionUtils.doIf(c -> isCritical(certificate, KEY_USAGE_OID) || requireKeyUsage,
t -> {
LOGGER.debug("KeyUsage extension is marked critical or required by configuration.");
return keyUsage[0];
},
f -> {
LOGGER.debug("KeyUsage digitalSignature=%s, Returning true since keyUsage validation not required by configuration.");
return Boolean.TRUE;
});
return func.apply(certificate);
}
/**
* Checks if is certificate allowed based no the pattern given.
*View on GitHub (pinned to e7288fc434)