{"record":{"id":"6e277678fdd4ded0","repo":"apereo/cas","slug":"yubikey-validation-failed","errorCode":null,"errorMessage":"YubiKey validation failed: ","messagePattern":"YubiKey validation failed: ","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-yubikey-core/src/main/java/org/apereo/cas/adaptors/yubikey/YubiKeyAuthenticationHandler.java","lineNumber":104,"sourceCode":"        val principal = authentication.getPrincipal();\n        val uid = principal.getId();\n        val publicId = registry.getAccountValidator().getTokenPublicId(otp);\n        if (!this.registry.isYubiKeyRegisteredFor(uid, publicId)) {\n            LOGGER.debug(\"YubiKey public id [{}] is not registered for user [{}]\", publicId, uid);\n            throw new AccountNotFoundException(\"YubiKey id is not recognized in registry\");\n        }\n\n        try {\n            val response = this.client.verify(otp);\n            val status = response.getStatus();\n            if (status.compareTo(ResponseStatus.OK) == 0) {\n                LOGGER.debug(\"YubiKey response status [{}] at [{}]\", status, response.getTimestamp());\n                return createHandlerResult(yubiKeyCredential, this.principalFactory.createPrincipal(uid));\n            }\n            throw new FailedLoginException(\"Authentication failed with status: \" + status);\n        } catch (final Throwable e) {\n            LoggingUtils.error(LOGGER, e);\n            throw new FailedLoginException(\"YubiKey validation failed: \" + e.getMessage());\n        }\n    }\n}\n","sourceCodeStart":86,"sourceCodeEnd":108,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-yubikey-core/src/main/java/org/apereo/cas/adaptors/yubikey/YubiKeyAuthenticationHandler.java#L86-L108","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before: firewalled host fails verification\n// after: route via internal validation server\ncas.authn.yubikey[0].api-server=https://ykval.internal.example.com/wsapi/2.0/verify\n// and/or set JVM proxy flags: -Dhttps.proxyHost=proxy -Dhttps.proxyPort=3128","handlingStrategy":"retry","validationCode":"// reachability probe before login flow\nnew URL(cas.authn.yubikey.apiServer or \"https://api.yubikey.com/wsapi/2.0/verify\")\n    .openConnection().connect(); // IOException means network issue","typeGuard":null,"tryCatchPattern":"try {\n    handler.authenticate(credential);\n} catch (FailedLoginException e) {\n    if (e.getMessage().startsWith(\"YubiKey validation failed\")) {\n        // transient network issue: back off and retry\n    }\n}","preventionTips":["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."],"tags":["yubikey","network","verification","wrapped-exception"],"backgroundTag":"network-request-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}