{"record":{"id":"ac053dc50b5c17b3","repo":"apereo/cas","slug":"password-does-not-match-value-on-record","errorCode":null,"errorMessage":"Password does not match value on record.","messagePattern":"Password does not match value on record\\.","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/QueryAndEncodeDatabaseAuthenticationHandler.java","lineNumber":58,"sourceCode":"    public QueryAndEncodeDatabaseAuthenticationHandler(final QueryEncodeJdbcAuthenticationProperties properties,\n\n                                                       final PrincipalFactory principalFactory,\n                                                       final DataSource dataSource,\n                                                       final DatabasePasswordEncoder databasePasswordEncoder) {\n        super(properties, principalFactory, dataSource);\n        this.databasePasswordEncoder = databasePasswordEncoder;\n    }\n\n    @Override\n    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(\n        final UsernamePasswordCredential transformedCredential, final String originalPassword) throws Throwable {\n        val username = transformedCredential.getUsername();\n        try {\n            val sqlQueryResults = performSqlQuery(username);\n            val digestedPassword = databasePasswordEncoder.encode(transformedCredential.toPassword(), sqlQueryResults);\n\n            if (!sqlQueryResults.get(properties.getPasswordFieldName()).equals(digestedPassword)) {\n                throw new FailedLoginException(\"Password does not match value on record.\");\n            }\n            if (StringUtils.isNotBlank(properties.getExpiredFieldName()) && sqlQueryResults.containsKey(properties.getExpiredFieldName())) {\n                val dbExpired = sqlQueryResults.get(properties.getExpiredFieldName()).toString();\n                if (BooleanUtils.toBoolean(dbExpired) || \"1\".equals(dbExpired)) {\n                    throw new AccountPasswordMustChangeException(\"Password has expired\");\n                }\n            }\n            if (StringUtils.isNotBlank(properties.getDisabledFieldName()) && sqlQueryResults.containsKey(properties.getDisabledFieldName())) {\n                val dbDisabled = sqlQueryResults.get(properties.getDisabledFieldName()).toString();\n                if (BooleanUtils.toBoolean(dbDisabled) || \"1\".equals(dbDisabled)) {\n                    throw new AccountDisabledException(\"Account has been disabled\");\n                }\n            }\n            val attributes = collectPrincipalAttributes(sqlQueryResults);\n            val principal = principalFactory.createPrincipal(username, attributes);\n            return createHandlerResult(transformedCredential, principal, new ArrayList<>());\n        } catch (final IncorrectResultSizeDataAccessException e) {\n            if (e.getActualSize() == 0) {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/QueryAndEncodeDatabaseAuthenticationHandler.java#L40-L76","documentation":"CAS's QueryAndEncodeDatabaseAuthenticationHandler throws FailedLoginException('Password does not match value on record.') when the password returned by the configured SQL query, after digesting the submitted password, does not equal the stored value. It is the handler's explicit 'wrong password' branch in authenticateUsernamePasswordInternal.","triggerScenarios":"User submits a credential whose transformed password, encoded via the configured PasswordEncoder (e.g. Md5PasswordEncoder with saltFieldName), does not equal the value in the column named by properties.getPasswordFieldName() of the single row returned by the SQL query.","commonSituations":"Wrong encoder/digest algorithm configured for the schema (SHA vs MD5 vs bcrypt), salt column missing or misnamed, password stored uppercase/lowercase vs digest casing, charset/encoding mismatch, user typo.","solutions":["Verify the configured passwordEncoder type, encoding and characterEncoding match how passwords were stored in the database","Confirm the saltFieldName column exists in the query results and holds the salt used at storage time","Compare a known digest of the test password against the stored value manually (SELECT ... WHERE username=...)","Check the SQL fieldPassword/passwordFieldName property points at the actual password column"],"exampleFix":"// before: schema stores SHA-512 hex but config uses default\n// cas.authn.jdbc.encode[0].passwordEncoder=DEFAULT\n// after\n// cas.authn.jdbc.encode[0].passwordEncoder=SHA-512\n// cas.authn.jdbc.encode[0].passwordEncoderCharsetName=UTF-8","handlingStrategy":"validation","validationCode":"// Before deploy, verify digesting matches storage for a known user\nString stored = jdbc.queryForObject(\"SELECT \" + passwordFieldName + \" FROM users WHERE username=?\", String.class, user);\nString encoded = passwordEncoder.encode(rawPassword, Map.of(saltFieldName, saltFromDb));\nif (!stored.equalsIgnoreCase(encoded)) throw new IllegalStateException(\"Encoder/schema mismatch for \" + user);","typeGuard":null,"tryCatchPattern":"try {\n    authResult = authenticationHandler.authenticate(credential);\n} catch (FailedLoginException e) {\n    // treat as bad credentials; do NOT leak encoder details to the user\n    audit.recordFailure(user, e.getMessage());\n    throw new BadCredentialsException(\"Invalid credentials\");\n}","preventionTips":["Pin the passwordEncoder type/encoding to exactly what the schema stores and test one known user at startup","Store a documented algorithm marker with each hash so schema/config drift is detectable","Keep charset settings (passwordEncoderCharsetName) explicit","Never mix DEFAULT encoder config with pre-hashed columns"],"tags":["jdbc","authentication","password-digest"],"backgroundTag":"password-verification-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"}