{"record":{"id":"6c258fe6185fe5c2","repo":"spring-projects/spring-security","slug":"username-cannot-be-null","errorCode":null,"errorMessage":"username cannot be null","messagePattern":"username cannot be null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosAuthenticationProvider.java","lineNumber":57,"sourceCode":"\tprivate @Nullable UserDetailsService userDetailsService;\n\n\t@Override\n\tpublic Authentication authenticate(Authentication authentication) throws AuthenticationException {\n\t\tUsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;\n\t\tif (this.kerberosClient == null) {\n\t\t\tthrow new IllegalStateException(\"kerberosClient must be set\");\n\t\t}\n\t\tif (this.userDetailsService == null) {\n\t\t\tthrow new IllegalStateException(\"userDetailsService must be set\");\n\t\t}\n\t\tObject credentials = auth.getCredentials();\n\t\tif (credentials == null) {\n\t\t\tthrow new IllegalArgumentException(\"credentials cannot be null\");\n\t\t}\n\t\tJaasSubjectHolder subjectHolder = this.kerberosClient.login(auth.getName(), credentials.toString());\n\t\tString username = subjectHolder.getUsername();\n\t\tif (username == null) {\n\t\t\tthrow new IllegalStateException(\"username cannot be null\");\n\t\t}\n\t\tUserDetails userDetails = this.userDetailsService.loadUserByUsername(username);\n\t\tKerberosUsernamePasswordAuthenticationToken output = new KerberosUsernamePasswordAuthenticationToken(\n\t\t\t\tuserDetails, credentials, userDetails.getAuthorities(), subjectHolder);\n\t\toutput.setDetails(authentication.getDetails());\n\t\treturn output;\n\n\t}\n\n\t@Override\n\tpublic boolean supports(Class<? extends Object> authentication) {\n\t\treturn (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));\n\t}\n\n\t/**\n\t * Sets the kerberos client.\n\t * @param kerberosClient the new kerberos client\n\t */","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosAuthenticationProvider.java#L39-L75","documentation":"After the KerberosClient login succeeds, the JaasSubjectHolder must yield a username to load the UserDetails. If the subject carries no principal name, the provider throws IllegalStateException(\"username cannot be null\").","triggerScenarios":"kerberosClient.login(name, password) returns a JaasSubjectHolder whose getUsername() is null — e.g. the JAAS login subject has no KerberosPrincipal or the client implementation doesn't extract the principal correctly.","commonSituations":"Custom JaasSubjectHolder/KerberosClient implementations that don't populate the username, or JAAS configuration whose login module attaches principals in a non-standard way.","solutions":["Inspect the JaasSubjectHolder/Subject to confirm a KerberosPrincipal is attached after login.","Fix or replace the custom KerberosClient so getUsername() extracts the principal name from the subject.","Check the JAAS login module configuration (keytab/krb5 settings) returns standard Kerberos principals.","Verify the krb5.conf realm mapping so the authenticated principal name is populated."],"exampleFix":"// before\n@Override\npublic String getUsername() { return null; }\n// after\n@Override\npublic String getUsername() {\n  Set<KerberosPrincipal> principals = subject.getPrincipals(KerberosPrincipal.class);\n  return principals.isEmpty() ? null : principals.iterator().next().getName();\n}","handlingStrategy":"validation","validationCode":"JaasSubjectHolder holder = kerberosClient.login(name, password);\nif (holder.getUsername() == null) {\n  throw new BadCredentialsException(\"Login subject has no KerberosPrincipal\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return authenticationManager.authenticate(auth);\n} catch (IllegalStateException e) {\n  LOG.error(\"Kerberos login produced no principal\", e);\n  throw new InternalAuthenticationServiceException(\"Kerberos login incomplete\", e);\n}","preventionTips":["Unit-test your KerberosClient implementation extracts a principal from the Subject.","Keep JAAS login module configuration standard (Krb5LoginModule).","Verify krb5.conf realm/principal mapping in staging."],"tags":["kerberos","jaas","invariant-violation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}