{"record":{"id":"16283c3b6ba47a52","repo":"apereo/cas","slug":"accountnotfoundexception","errorCode":null,"errorMessage":"AccountNotFoundException","messagePattern":"AccountNotFoundException","errorType":"exception","errorClass":"AccountNotFoundException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-redis-authentication/src/main/java/org/apereo/cas/redis/RedisAuthenticationHandler.java","lineNumber":37,"sourceCode":" */\n@Slf4j\npublic class RedisAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {\n    private final CasRedisTemplate redisTemplate;\n\n    public RedisAuthenticationHandler(final String name,\n                                      final PrincipalFactory principalFactory, final Integer order,\n                                      final CasRedisTemplate redisTemplate) {\n        super(name, principalFactory, order);\n        this.redisTemplate = redisTemplate;\n    }\n\n    @Override\n    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(\n        final UsernamePasswordCredential credential,\n        final String originalPassword) throws Throwable {\n        val account = (RedisUserAccount) redisTemplate.opsForValue().get(credential.getUsername());\n        if (account == null) {\n            throw new AccountNotFoundException();\n        }\n        if (!getPasswordEncoder().matches(originalPassword, account.getPassword())) {\n            LOGGER.warn(\"Account password on record for [{}] does not match the given/encoded password\", credential.getId());\n            throw new FailedLoginException();\n        }\n        switch (account.getStatus()) {\n            case DISABLED -> throw new AccountDisabledException();\n            case EXPIRED -> throw new AccountExpiredException();\n            case LOCKED -> throw new AccountLockedException();\n            case MUST_CHANGE_PASSWORD -> throw new AccountPasswordMustChangeException();\n            case OK -> LOGGER.debug(\"Account status is OK\");\n        }\n        val principal = principalFactory.createPrincipal(account.getUsername(), account.getAttributes());\n        return createHandlerResult(credential, principal, new ArrayList<>());\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":54,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-redis-authentication/src/main/java/org/apereo/cas/redis/RedisAuthenticationHandler.java#L19-L54","documentation":"RedisAuthenticationHandler.authenticateUsernamePasswordInternal throws AccountNotFoundException (no-arg, so the message is just the class name) when redisTemplate has no value stored under credential.getUsername() — i.e. the user account does not exist in Redis.","triggerScenarios":"A login attempt where GET <username> on the configured Redis template returns null: key never written, wrong Redis database/index configured, key expired or evicted, or key naming/prefix mismatch.","commonSituations":"User provisioning never loaded accounts into Redis; Redis flushed or running against the wrong logical DB (spring.data.redis.database); TTL expiry removed the account; username case sensitivity mismatch between CAS and the provisioning writer.","solutions":["Provision/load the user account into Redis under the exact username key","Verify CAS and the provisioning tool point at the same Redis host, port, database and key prefix","Check for TTL/eviction policies (maxmemory-policy) deleting account keys","Confirm the username casing matches exactly what is stored in Redis"],"exampleFix":"// provisioning (before login)\nredisTemplate.opsForValue().set(\"jsmith\", new RedisUserAccount(\"jsmith\", encoder.encode(\"secret\"), Status.OK, attrs));\n// then CAS login with credential username 'jsmith' succeeds instead of throwing AccountNotFoundException","handlingStrategy":"validation","validationCode":"Object raw = redisTemplate.opsForValue().get(username);\nif (raw == null) {\n    // account not provisioned; skip login or trigger provisioning\n}","typeGuard":"boolean accountExists(RedisTemplate<String,Object> tpl, String username) {\n    return Boolean.TRUE.equals(tpl.hasKey(username));\n}","tryCatchPattern":"try {\n    authHandler.authenticate(credential);\n} catch (AccountNotFoundException e) {\n    // 'user not registered' messaging\n}","preventionTips":["Provision accounts before enabling Redis authentication","Pin the same Redis database/index for writer and CAS","Avoid volatile eviction policies for account keys","Normalize username casing"],"tags":["redis","account-not-found","authentication","cas"],"backgroundTag":"user-not-found","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"}