{"record":{"id":"7eaf02c62f79f916","repo":"apereo/cas","slug":"transformed-username-is-null","errorCode":null,"errorMessage":"Transformed username is null.","messagePattern":"Transformed 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":73,"sourceCode":"                                                                       @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":55,"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#L55-L81","documentation":"transformUsername throws AccountNotFoundException when the configured principalNameTransformer transforms the credential id into a blank string. The raw id was present, but after applying the transformation (regex strip, truncation, script, etc.) nothing remained, so the account is treated as not found.","triggerScenarios":"Calling transformUsername with a valid non-blank credential id whose principalNameTransformer.transform(...) returns null or empty — e.g. a regex/ groovy transformer whose pattern fails to match, or one configured to cut the id to zero length.","commonSituations":"Principal name transformer regex that doesn't match the actual username format (e.g. domain-stripping pattern against plain usernames); misconfigured Groovy/JS transformer script returning null; transformer configured for one handler family but the credential format differs (email vs uid).","solutions":["Review the configured principalNameTransformer and test it against the actual submitted username format.","Fix the transformer pattern/script so it returns a non-empty value, or add a fallback return of the original id.","Remove the transformer if no transformation is needed (default transformer returns the input).","Log the raw and transformed values to pinpoint the mismatch.","Validate username format upstream (form validation) so only matching values reach the transformer."],"exampleFix":"// before (Groovy transformer script)\ndef run(Object[] args) { return args[0].toString().replaceAll('^.*\\\\\\\\\\\\\\|', '') } // strips everything when no backslash\n// after\ndef run(Object[] args) { def u = args[0].toString(); def i = u.indexOf('\\\\\\\\'); return i >= 0 ? u.substring(i + 1) : u }","handlingStrategy":"validation","validationCode":"// preflight the transformer against real username formats\nString out = principalNameTransformer.transform(\"jdoe@example.org\");\nif (StringUtils.isBlank(out)) { throw new IllegalStateException(\"Transformer returns blank for valid usernames\"); }","typeGuard":null,"tryCatchPattern":"try {\n    return handler.authenticate(credential, service);\n} catch (AccountNotFoundException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Transformed username\")) {\n        LOGGER.error(\"Principal name transformer produced empty value; check regex/script\", e);\n    }\n    throw e;\n}","preventionTips":["Unit test the principal name transformer with all username formats in use (uid, email, DOMAIN\\\\user).","Prefer transformers that return the original value when the pattern doesn't match.","Log raw vs transformed values when debugging transformer issues."],"tags":["authentication","username-transformation","principal-name"],"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"}