spring-projects/spring-security · error · IllegalStateException

userDetailsService must be set

Error message

userDetailsService must be set

What it means

KerberosAuthenticationProvider needs a UserDetailsService to load the authenticated user. It throws IllegalStateException in authenticate() when `userDetailsService` was never set, indicating incomplete provider configuration.

Source

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

 *
 * @author Mike Wiesner
 * @author Bogdan Mustiata
 * @since 1.0
 */
public class KerberosAuthenticationProvider implements AuthenticationProvider {

	private @Nullable KerberosClient kerberosClient;

	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;

	}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Call setUserDetailsService(...) with a UserDetailsService (e.g. a KerberosUserDetailsService or your own) before authentication requests arrive.
  2. Ensure the UserDetailsService bean is in the application context and injected into the provider.
  3. Double-check afterPropertiesSet/bean lifecycle so the provider is validated at startup rather than at request time.

Example fix

// before
KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
provider.setKerberosClient(client);
// after
KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
provider.setKerberosClient(client);
provider.setUserDetailsService(new KerberosUserDetailsService());
Defensive patterns

Strategy: validation

Validate before calling

if (provider instanceof KerberosAuthenticationProvider k && k.getUserDetailsService() == null) throw new IllegalStateException("userDetailsService not wired");

Try / catch

try {
  return authenticationManager.authenticate(auth);
} catch (IllegalStateException e) {
  LOG.error("Provider missing userDetailsService: {}", e.getMessage());
  throw e;
}

Prevention

When it happens

Trigger: Registering a KerberosAuthenticationProvider without calling setUserDetailsService, then handling an authentication request.

Common situations: Bean wiring mistakes in security configuration, or refactoring that removed the UserDetailsService bean leaving the provider unconfigured.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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