{"record":{"id":"b4c0b71c0fbd98da","repo":"apereo/cas","slug":"username-is-null","errorCode":null,"errorMessage":"Username is null.","messagePattern":"Username is null\\.","errorType":"exception","errorClass":"AccountNotFoundException","httpStatus":null,"severity":"error","filePath":"core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/AbstractPreAndPostProcessingAuthenticationHandler.java","lineNumber":68,"sourceCode":"\n    protected abstract AuthenticationHandlerExecutionResult doAuthentication(Credential credential, Service service)\n        throws Throwable;\n\n    protected AuthenticationHandlerExecutionResult createHandlerResult(final Credential credential,\n                                                                       @Nullable final Principal principal,\n                                                                       @Nullable final List<MessageDescriptor> warnings) {\n        return new DefaultAuthenticationHandlerExecutionResult(this, credential, principal, warnings);\n    }\n\n    protected AuthenticationHandlerExecutionResult createHandlerResult(final Credential credential,\n                                                                       final Principal principal) {\n        return new DefaultAuthenticationHandlerExecutionResult(this, credential,\n            principal, new ArrayList<>());\n    }\n\n    protected String transformUsername(final Credential credential) throws Throwable {\n        if (StringUtils.isBlank(credential.getId())) {\n            throw new AccountNotFoundException(\"Username is null.\");\n        }\n        LOGGER.debug(\"Transforming credential username via [{}]\", principalNameTransformer.getClass().getName());\n        val transformedUsername = principalNameTransformer.transform(credential.getId());\n        if (StringUtils.isBlank(transformedUsername)) {\n            throw new AccountNotFoundException(\"Transformed username is null.\");\n        }\n        if (credential instanceof final MutableCredential mc) {\n            mc.setId(transformedUsername);\n        }\n        return transformedUsername;\n    }\n}\n","sourceCodeStart":50,"sourceCodeEnd":81,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/AbstractPreAndPostProcessingAuthenticationHandler.java#L50-L81","documentation":"transformUsername in AbstractPreAndPostProcessingAuthenticationHandler throws AccountNotFoundException when credential.getId() is blank. The handler refuses to run the principal-name transformer on an empty identifier, treating the credential as an unknown account rather than a generic failure.","triggerScenarios":"authenticate()/doAuthentication path invokes transformUsername with a credential whose id is null or empty — e.g. an empty username field in the login form that passed earlier extraction, or a custom credential constructed without setting an id.","commonSituations":"Blank username submitted in the login form; form binding names mismatching the extractor so id never gets populated; scripted/REST clients posting credentials with an empty principal; custom Credential subclass forgetting to set the id in its constructor.","solutions":["Ensure the username parameter is present and non-empty before invoking the handler; validate at the webflow/form level.","Check that the credential extractor maps the correct request parameter to Credential.getId().","Fix custom Credential construction to always supply a non-blank id.","Configure client-side / webflow validation to reject blank usernames before authentication.","If blank usernames should fail differently, override transformUsername in the subclass."],"exampleFix":"// before\nval cred = new UsernamePasswordCredential(\"\", password);\nhandler.authenticate(cred, null);\n// after\nif (StringUtils.isBlank(username)) { throw new IllegalArgumentException(\"username required\"); }\nval cred = new UsernamePasswordCredential(username, password);\nhandler.authenticate(cred, null);","handlingStrategy":"validation","validationCode":"// before invoking the handler\nif (credential == null || StringUtils.isBlank(credential.getId())) {\n    throw new IllegalArgumentException(\"credential id (username) is required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return handler.authenticate(credential, service);\n} catch (AccountNotFoundException e) {\n    LOGGER.warn(\"Blank or unknown username submitted\", e);\n    throw new BadCredentialsAuthenticationException(\"username required\");\n}","preventionTips":["Validate the username field client- and server-side before authentication.","Ensure credential extractors bind the correct request parameter into Credential.getId().","Add tests covering empty-username submissions end to end."],"tags":["authentication","username","validation"],"backgroundTag":"empty-required-field","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"}