spring-projects/spring-security · warning

Found %s UserDetailsService beans, with names %s. Global Aut

Error message

Found %s UserDetailsService beans, with names %s. Global Authentication Manager will not use a UserDetailsService for username/password login. Consider publishing a single UserDetailsService bean.

What it means

When the global AuthenticationManager would otherwise be built from a UserDetailsService bean, InitializeUserDetailsBeanManagerConfigurer looks for exactly one such bean. If it finds more than one, it cannot pick one, skips auto-configuration of username/password login entirely, and logs this warning listing the bean names and count.

Source

Thrown at config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java:88

			String[] beanNames = InitializeUserDetailsBeanManagerConfigurer.this.context
				.getBeanNamesForType(UserDetailsService.class);
			if (auth.isConfigured()) {
				if (beanNames.length > 0) {
					this.logger.warn("Global AuthenticationManager configured with an AuthenticationProvider bean. "
							+ "UserDetailsService beans will not be used by Spring Security for automatically configuring username/password login. "
							+ "Consider removing the AuthenticationProvider bean. "
							+ "Alternatively, consider using the UserDetailsService in a manually instantiated DaoAuthenticationProvider. "
							+ "If the current configuration is intentional, to turn off this warning, "
							+ "increase the logging level of 'org.springframework.security.config.annotation.authentication.configuration.InitializeUserDetailsBeanManagerConfigurer' to ERROR");
				}
				return;
			}

			if (beanNames.length == 0) {
				return;
			}
			else if (beanNames.length > 1) {
				this.logger.warn(LogMessage.format("Found %s UserDetailsService beans, with names %s. "
						+ "Global Authentication Manager will not use a UserDetailsService for username/password login. "
						+ "Consider publishing a single UserDetailsService bean.", beanNames.length,
						Arrays.toString(beanNames)));
				return;
			}
			UserDetailsService userDetailsService = InitializeUserDetailsBeanManagerConfigurer.this.context
				.getBean(beanNames[0], UserDetailsService.class);
			PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
			UserDetailsPasswordService passwordManager = getBeanOrNull(UserDetailsPasswordService.class);
			CompromisedPasswordChecker passwordChecker = getBeanOrNull(CompromisedPasswordChecker.class);
			DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService);
			if (passwordEncoder != null) {
				provider.setPasswordEncoder(passwordEncoder);
			}
			if (passwordManager != null) {
				provider.setUserDetailsPasswordService(passwordManager);
			}
			if (passwordChecker != null) {

View on GitHub (pinned to 96852e8860)

Solutions

  1. Publish exactly one UserDetailsService bean; delete or @Primary-free consolidate the duplicates.
  2. Mark the intended bean @Primary so only it is considered, and remove or rename the others.
  3. If multiple are needed, build the AuthenticationManager explicitly (e.g. AuthenticationManagerBuilder or a DaoAuthenticationProvider per store) instead of relying on auto-configuration.

Example fix

// before
@Bean UserDetailsService ldapUds() { return new LdapUserDetailsService(); }
@Bean UserDetailsService dbUds() { return new JdbcUserDetailsService(); }

// after
@Bean
@Primary
UserDetailsService dbUds() { return new JdbcUserDetailsService(); }
Defensive patterns

Strategy: validation

Validate before calling

String[] names = ctx.getBeanNamesForType(UserDetailsService.class);
if (names.length > 1) {
    throw new IllegalStateException("Expected exactly one UserDetailsService bean, found: " + Arrays.toString(names));
}

Prevention

When it happens

Trigger: Declaring two or more UserDetailsService beans in the ApplicationContext (e.g. two @Bean methods or @Component services implementing UserDetailsService) with no explicit AuthenticationProvider/AuthenticationManager configured, then triggering AuthenticationManager initialization.

Common situations: Having both a Spring Boot auto-configured InMemoryUserDetailsManager and an app-defined UserDetailsService; multiple modules each publishing their own UserDetailsService; test configurations importing extra user-details beans.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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