apereo/cas · error · FailedLoginException
Authentication failed with status:
Error message
Authentication failed with status:
What it means
After a successful registry check, the handler calls client.verify(otp) against YubiCloud; if the response status is anything other than OK, it throws FailedLoginException("Authentication failed with status: " + status). This is the standard bad-OTP/verification-failure path of the YubiKey handler.
Solutions
- Have the user generate a fresh OTP by touching the YubiKey; do not replay previous OTPs.
- Verify cas.authn.yubikey[0].client-id and secret-key are correct YubiCloud API credentials.
- Check outbound connectivity to api.yubikey.com and NTP-synced system time to avoid signature errors.
- Inspect the logged status value to identify the specific YubiCloud failure and address it.
Example fix
// before cas.authn.yubikey[0].client-id=change-me // after cas.authn.yubikey[0].client-id=12345 cas.authn.yubikey[0].secret-key=base64secret==
Defensive patterns
Strategy: try-catch
Validate before calling
// check OTP shape (device prefix length) before submit
if (otp == null || otp.length() < 32 || otp.length() > 48) throw new IllegalArgumentException("malformed OTP"); Try / catch
try {
handler.authenticate(credential);
} catch (FailedLoginException e) {
// read YubiCloud status from message, prompt user for a fresh OTP
} Prevention
- Instruct users to touch the YubiKey to generate a new OTP each attempt (no copy/paste reuse).
- Configure valid YubiCloud client id/secret and verify them with a test call.
- Keep server clocks NTP-synced to avoid signature rejections.
When it happens
Trigger: YubiCloud returns a non-OK status (BAD_OTP, REPLAYED_OTP, BAD_SIGNATURE, MISSING_PARAMETER, etc.) for a YubiKey OTP submitted by a registered user.
Common situations: User mistypes the OTP or reuses an old one (replayed); server clock/signature issues cause BAD_SIGNATURE; wrong client id/secret configured; OTP copied incompletely.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- OTP format is invalid
- YubiKey id is not recognized in registry
- Authorization of OTP token
- Authentication handler is disabled
- No user can be accepted because none is defined
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/d1069f0182d02bbf.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-yubikey-core/src/main/java/org/apereo/cas/adaptors/yubikey/YubiKeyAuthenticationHandler.java:101
val authentication = Objects.requireNonNull(WebUtils.getInProgressAuthentication(),
"CAS has no reference to an authentication event to locate a principal");
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)