apereo/cas · error · FailedLoginException
YubiKey validation failed:
Error message
YubiKey validation failed:
What it means
The catch-all Throwable handler in doAuthentication logs the original error and rethrows FailedLoginException("YubiKey validation failed: " + cause.getMessage()). It wraps any exception during the YubiCloud verification call (network failure, client construction error, runtime exceptions) into a generic login failure.
Solutions
- Read the wrapped cause message in the log (LoggingUtils.error prints the full stack) to find the root failure.
- Test outbound HTTPS connectivity from the CAS host to api.yubikey.com; configure proxy if needed.
- Correct cas.authn.yubikey[0].client-id / secret-key credentials.
- If YubiCloud is down or unreachable, switch cas.authn.yubikey[0].api-server to an on-prem ykval validation server URL.
Example fix
// before: firewalled host fails verification // after: route via internal validation server cas.authn.yubikey[0].api-server=https://ykval.internal.example.com/wsapi/2.0/verify // and/or set JVM proxy flags: -Dhttps.proxyHost=proxy -Dhttps.proxyPort=3128
Defensive patterns
Strategy: retry
Validate before calling
// reachability probe before login flow
new URL(cas.authn.yubikey.apiServer or "https://api.yubikey.com/wsapi/2.0/verify")
.openConnection().connect(); // IOException means network issue Try / catch
try {
handler.authenticate(credential);
} catch (FailedLoginException e) {
if (e.getMessage().startsWith("YubiKey validation failed")) {
// transient network issue: back off and retry
}
} Prevention
- Verify outbound HTTPS from CAS hosts to api.yubikey.com; configure proxy flags in the JVM.
- Consider an on-prem ykval validation server for air-gapped deployments.
- Monitor YubiCloud status and set sensible client timeouts.
When it happens
Trigger: client.verify(otp) throws: network unreachable/DNS failure to YubiCloud, invalid API credentials causing client errors, timeouts, or any runtime exception inside the verify path.
Common situations: CAS server has no outbound internet access or a proxy is required; wrong client id/secret; YubiCloud outage; firewall blocks api.yubikey.com (port 443).
Related errors
- not in allowed range.
- Unexpected LDAP error
- Failed to acquire access token
- Cannot login user using CAS internal authentication
- Radius authentication failed
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/6e277678fdd4ded0.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-yubikey-core/src/main/java/org/apereo/cas/adaptors/yubikey/YubiKeyAuthenticationHandler.java:104
val principal = authentication.getPrincipal();
val uid = principal.getId();
val publicId = registry.getAccountValidator().getTokenPublicId(otp);
if (!this.registry.isYubiKeyRegisteredFor(uid, publicId)) {
LOGGER.debug("YubiKey public id [{}] is not registered for user [{}]", publicId, uid);
throw new AccountNotFoundException("YubiKey id is not recognized in registry");
}
try {
val response = this.client.verify(otp);
val status = response.getStatus();
if (status.compareTo(ResponseStatus.OK) == 0) {
LOGGER.debug("YubiKey response status [{}] at [{}]", status, response.getTimestamp());
return createHandlerResult(yubiKeyCredential, this.principalFactory.createPrincipal(uid));
}
throw new FailedLoginException("Authentication failed with status: " + status);
} catch (final Throwable e) {
LoggingUtils.error(LOGGER, e);
throw new FailedLoginException("YubiKey validation failed: " + e.getMessage());
}
}
}
View on GitHub (pinned to e7288fc434)