spring-projects/spring-security · error · IllegalStateException

username cannot be null

Error message

username cannot be null

What it means

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").

Source

Thrown at kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosAuthenticationProvider.java:57

	private @Nullable UserDetailsService userDetailsService;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
		if (this.kerberosClient == null) {
			throw new IllegalStateException("kerberosClient must be set");
		}
		if (this.userDetailsService == null) {
			throw new IllegalStateException("userDetailsService must be set");
		}
		Object credentials = auth.getCredentials();
		if (credentials == null) {
			throw new IllegalArgumentException("credentials cannot be null");
		}
		JaasSubjectHolder subjectHolder = this.kerberosClient.login(auth.getName(), credentials.toString());
		String username = subjectHolder.getUsername();
		if (username == null) {
			throw new IllegalStateException("username cannot be null");
		}
		UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
		KerberosUsernamePasswordAuthenticationToken output = new KerberosUsernamePasswordAuthenticationToken(
				userDetails, credentials, userDetails.getAuthorities(), subjectHolder);
		output.setDetails(authentication.getDetails());
		return output;

	}

	@Override
	public boolean supports(Class<? extends Object> authentication) {
		return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
	}

	/**
	 * Sets the kerberos client.
	 * @param kerberosClient the new kerberos client
	 */

View on GitHub (pinned to 96852e8860)

Solutions

  1. Inspect the JaasSubjectHolder/Subject to confirm a KerberosPrincipal is attached after login.
  2. Fix or replace the custom KerberosClient so getUsername() extracts the principal name from the subject.
  3. Check the JAAS login module configuration (keytab/krb5 settings) returns standard Kerberos principals.
  4. Verify the krb5.conf realm mapping so the authenticated principal name is populated.

Example fix

// before
@Override
public String getUsername() { return null; }
// after
@Override
public String getUsername() {
  Set<KerberosPrincipal> principals = subject.getPrincipals(KerberosPrincipal.class);
  return principals.isEmpty() ? null : principals.iterator().next().getName();
}
Defensive patterns

Strategy: validation

Validate before calling

JaasSubjectHolder holder = kerberosClient.login(name, password);
if (holder.getUsername() == null) {
  throw new BadCredentialsException("Login subject has no KerberosPrincipal");
}

Try / catch

try {
  return authenticationManager.authenticate(auth);
} catch (IllegalStateException e) {
  LOG.error("Kerberos login produced no principal", e);
  throw new InternalAuthenticationServiceException("Kerberos login incomplete", e);
}

Prevention

When it happens

Trigger: 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.

Common situations: Custom JaasSubjectHolder/KerberosClient implementations that don't populate the username, or JAAS configuration whose login module attaches principals in a non-standard way.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/6c258fe6185fe5c2. Report an issue: GitHub.