{"record":{"id":"ece2de7500d15efc","repo":"apereo/cas","slug":"no-records-found-for-user-username","errorCode":null,"errorMessage":"No records found for user [username]","messagePattern":"No records found for user \\[username\\]","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/QueryDatabaseAuthenticationHandler.java","lineNumber":79,"sourceCode":"                val originalPasswordEquals = StringUtils.isBlank(originalPassword) && !Strings.CI.equals(password, dbPassword);\n                if (originalPasswordMatchFails || originalPasswordEquals) {\n                    throw new FailedLoginException(\"Password does not match value on record.\");\n                }\n            } else {\n                LOGGER.debug(\"Password field is not found in the query results. Checking for result count...\");\n                if (!dbFields.containsKey(\"total\")) {\n                    throw new FailedLoginException(\"Missing field 'total' from the query results for \" + username);\n                }\n\n                val count = dbFields.get(\"total\");\n                if (count == null || !NumberUtils.isCreatable(count.toString())) {\n                    throw new FailedLoginException(\"Missing field value 'total' from the query results for \"\n                        + username + \" or value not parseable as a number\");\n                }\n\n                val number = NumberUtils.createNumber(count.toString());\n                if (number.longValue() != 1) {\n                    throw new FailedLoginException(\"No records found for user \" + username);\n                }\n            }\n\n            if (StringUtils.isNotBlank(properties.getFieldDisabled()) && dbFields.containsKey(properties.getFieldDisabled())) {\n                val dbDisabled = dbFields.get(properties.getFieldDisabled()).toString();\n                if (BooleanUtils.toBoolean(dbDisabled) || \"1\".equals(dbDisabled)) {\n                    throw new AccountDisabledException(\"Account has been disabled\");\n                }\n            }\n            if (StringUtils.isNotBlank(properties.getFieldExpired()) && dbFields.containsKey(properties.getFieldExpired())) {\n                val dbExpired = dbFields.get(properties.getFieldExpired()).toString();\n                if (BooleanUtils.toBoolean(dbExpired) || \"1\".equals(dbExpired)) {\n                    throw new AccountPasswordMustChangeException(\"Password has expired\");\n                }\n            }\n\n            val attributes = collectPrincipalAttributes(dbFields);\n            val principal = this.principalFactory.createPrincipal(username, attributes);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/QueryDatabaseAuthenticationHandler.java#L61-L97","documentation":"Using the count-based contract, the handler throws FailedLoginException('No records found for user [username]') when the 'total' value parses but is not exactly 1. Only a single matching record authenticates; zero matches (unknown user) and multiple matches (bad schema) both land here.","triggerScenarios":"NumberUtils.createNumber(total.toString()).longValue() != 1 — typically COUNT(*) = 0 because no row matches the username, or > 1 because of duplicates.","commonSituations":"Unknown user (count 0), duplicate usernames without a unique constraint (count > 1), case-insensitive duplicates, wrong WHERE clause joining multiple rows.","solutions":["Confirm the user exists if count is 0 (data or username problem)","Deduplicate rows and enforce a unique constraint if count > 1","Check the SQL WHERE clause matches exactly one row per user","Add explicit AccountNotFoundException handling upstream if you need to distinguish 0 from >1"],"exampleFix":"// before: duplicates allowed\n// CREATE TABLE users(username VARCHAR(255), ...);\n// after\n// CREATE UNIQUE INDEX ux_users_username ON users(username);","handlingStrategy":"validation","validationCode":"int total = jdbc.queryForObject(\"SELECT COUNT(*) FROM users WHERE username=?\", Integer.class, user);\nif (total != 1) throw new IllegalStateException(\"Expected exactly 1 user row for \" + user + \", found \" + total);","typeGuard":null,"tryCatchPattern":"try {\n    authResult = handler.authenticate(credential);\n} catch (FailedLoginException e) {\n    if (e.getMessage().startsWith(\"No records found\")) {\n        // 0 => unknown user, >1 => duplicates; both are data issues, return generic failure\n        audit.logNoSingleRecord(user);\n        throw new BadCredentialsException(\"Invalid credentials\");\n    }\n    throw e;\n}","preventionTips":["Enforce a unique constraint on the username column so total can never exceed 1","Use COUNT(*) AS total in the sql exactly once","Provision users before enabling login against this source","Treat total!=1 alerts as data-integrity incidents"],"tags":["jdbc","count-query","user-lookup"],"backgroundTag":"empty-result-set","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"}