{"record":{"id":"cc8e237cdc8e574c","repo":"apereo/cas","slug":"password-is-null","errorCode":null,"errorMessage":"Password is null.","messagePattern":"Password is null\\.","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/AbstractUsernamePasswordAuthenticationHandler.java","lineNumber":83,"sourceCode":"    @Override\n    public boolean supports(final Class<? extends Credential> clazz) {\n        return UsernamePasswordCredential.class.isAssignableFrom(clazz);\n    }\n\n    @Override\n    protected AuthenticationHandlerExecutionResult doAuthentication(final Credential credential, final Service service) throws Throwable {\n        val originalUserPass = (UsernamePasswordCredential) credential;\n        val userPass = new UsernamePasswordCredential();\n        FunctionUtils.doUnchecked(_ -> BeanUtils.copyProperties(userPass, originalUserPass));\n        transformUsername(userPass);\n        transformPassword(userPass);\n        LOGGER.debug(\"Attempting authentication internally for transformed credential [{}]\", userPass);\n        return authenticateUsernamePasswordInternal(userPass, originalUserPass.toPassword());\n    }\n\n    protected void transformPassword(final UsernamePasswordCredential userPass) throws FailedLoginException, AccountNotFoundException {\n        if (StringUtils.isBlank(userPass.toPassword())) {\n            throw new FailedLoginException(\"Password is null.\");\n        }\n        LOGGER.debug(\"Attempting to encode credential password via [{}] for [{}]\", passwordEncoder.getClass().getName(), userPass.getUsername());\n        val transformedPsw = passwordEncoder.encode(userPass.toPassword());\n        if (StringUtils.isBlank(transformedPsw)) {\n            throw new AccountNotFoundException(\"Encoded password is null.\");\n        }\n        userPass.assignPassword(transformedPsw);\n    }\n    \n    /**\n     * Authenticates a username/password credential by an arbitrary strategy with extra parameter original credential password before\n     * encoding password. Override it if implementation need to use original password for authentication.\n     *\n     * @param credential       the credential object bearing the transformed username and password.\n     * @param originalPassword original password from credential before password encoding\n     * @return AuthenticationHandlerExecutionResult resolved from credential on authentication success or null if no principal could be resolved from the credential.\n     * @throws Throwable the throwable\n     */","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/AbstractUsernamePasswordAuthenticationHandler.java#L65-L101","documentation":"transformPassword in AbstractUsernamePasswordAuthenticationHandler throws FailedLoginException when the credential's password is blank before any encoding is attempted. CAS treats a missing password as an outright login failure rather than running it through the PasswordEncoder.","triggerScenarios":"doAuthentication -> authenticateUsernamePasswordInternal path invokes transformPassword with a UsernamePasswordCredential whose toPassword() returns null or empty — i.e. the password field was absent, empty, or never bound into the credential.","commonSituations":"Login form submitted with empty password field; password parameter name mismatch between form and extractor; API/REST authentication clients omitting the password attribute; password stripped by prior custom processing.","solutions":["Require and validate a non-empty password in the form/webflow before calling the handler.","Check that the extractor maps the password request parameter correctly (form field name typos).","Fix REST/API clients to include the password in the request payload.","Inspect any custom code that mutates the credential before authentication and may blank the password.","If the password arrives encrypted, ensure decryption preprocessing hasn't produced an empty value."],"exampleFix":"// before\nval cred = new UsernamePasswordCredential(username, \"\");\n// after\nif (StringUtils.isBlank(password)) { throw new BindException(\"password required\"); }\nval cred = new UsernamePasswordCredential(username, password);","handlingStrategy":"validation","validationCode":"// before authentication\nif (password == null || password.isEmpty()) {\n    throw new IllegalArgumentException(\"password is required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return handler.authenticate(credential, service);\n} catch (FailedLoginException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Password is null\")) {\n        LOGGER.error(\"Empty password credential reached the handler; check extractor/form binding\");\n    }\n    throw new BadCredentialsAuthenticationException();\n}","preventionTips":["Require non-empty passwords in form/webflow validation.","Verify password field names match the credential extractor mapping.","For REST clients, document and validate the required password payload field."],"tags":["authentication","password","validation"],"backgroundTag":"missing-credentials","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"}