apereo/cas · error · FailedLoginException
Certificate keyUsage constraint forbids SSL client…
Error message
Certificate keyUsage constraint forbids SSL client authentication.
What it means
When checkKeyUsage is enabled, X509CredentialsAuthenticationHandler.validate() verifies that an end-entity certificate's keyUsage extension permits SSL/TLS client authentication. If isValidKeyUsage() finds the required bits absent (or the extension missing), it throws FailedLoginException.
Solutions
- Set cas.authn.x509.check-key-usage=false if your PKI does not populate keyUsage for client certs.
- Re-issue the client certificate with keyUsage including digitalSignature (plus keyEncipherment as appropriate for TLS client auth).
- Use a certificate explicitly issued for client authentication.
- Inspect the cert with: openssl x509 -in cert.pem -noout -ext keyUsage.
Example fix
// before cas.authn.x509.check-key-usage=true // after cas.authn.x509.check-key-usage=false
Defensive patterns
Strategy: validation
Validate before calling
boolean[] ku = cert.getKeyUsage();
boolean ok = ku != null && ((ku[0] /* digitalSignature */));
if (!ok) { reject("cert not usable for client auth"); } Type guard
boolean supportsClientAuth(X509Certificate cert) {
boolean[] ku = cert.getKeyUsage();
return ku != null && ku.length > 0 && ku[0];
} Try / catch
try {
handler.authenticate(credential);
} catch (FailedLoginException e) {
// keyUsage forbids client authentication: re-issue cert or relax checkKeyUsage
} Prevention
- Issue client certificates with digitalSignature (and keyEncipherment) keyUsage bits.
- Only enable check-key-usage if the PKI reliably populates keyUsage.
- Inspect certs with openssl x509 -ext keyUsage before enrollment.
- Document required keyUsage in your certificate policy.
When it happens
Trigger: cas.authn.x509.check-key-usage=true and the presented end-entity certificate's keyUsage bits do not satisfy the client-auth requirement (e.g. no digitalSignature/keyEncipherment bits).
Common situations: Certificates issued for serverAuth or code signing used as client certs; PKI re-issue dropping the digitalSignature bit; checkKeyUsage enabled while the CA issues certs without any keyUsage extension.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Certificate subject does not match pattern
- Unable to accept certificate
- No Certificates provided
- Expired or invalid certificate in metadata for
- Unlimited certificate path length not allowed by…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/076630e7ab7272b6.
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:243
LOGGER.warn("Either client certificate could not be determined, or a trusted issuer could not be located");
throw new FailedLoginException();
}
private void validate(final X509Certificate cert) throws GeneralSecurityException {
cert.checkValidity();
this.revocationChecker.check(cert);
val pathLength = cert.getBasicConstraints();
if (pathLength < 0) {
if (!isCertificateAllowed(cert)) {
val msg = "Certificate subject does not match pattern " + this.regExSubjectDnPattern.pattern();
LOGGER.error(msg);
throw new FailedLoginException(msg);
}
if (this.checkKeyUsage && !isValidKeyUsage(cert)) {
val msg = "Certificate keyUsage constraint forbids SSL client authentication.";
LOGGER.error(msg);
throw new FailedLoginException(msg);
}
} else {
if (pathLength == Integer.MAX_VALUE && !this.maxPathLengthAllowUnspecified) {
val msg = "Unlimited certificate path length not allowed by configuration.";
LOGGER.error(msg);
throw new FailedLoginException(msg);
}
if (pathLength > this.maxPathLength && pathLength < Integer.MAX_VALUE) {
val msg = String.format("Certificate path length %s exceeds maximum value %s.", pathLength, this.maxPathLength);
LOGGER.error(msg);
throw new FailedLoginException(msg);
}
}
}
/**
* Checks if is valid key usage. <p>
* KeyUsage ::= BIT STRING { digitalSignature (0), nonRepudiation (1),View on GitHub (pinned to e7288fc434)