spring-projects/spring-security · error · ApplicationContextException

More than one UserDetailsService registered. Please use a sp

Error message

More than one UserDetailsService registered. Please use a specific Id reference in <remember-me/> or <x509 /> elements.

What it means

When getUserDetailsService() finds multiple UserDetailsService beans and no explicit reference was given, Spring Security cannot decide which one backs remember-me/x509 token authentication, so it fails with this exception directing the user to disambiguate.

Source

Thrown at config/src/main/java/org/springframework/security/config/http/UserDetailsServiceFactoryBean.java:111

		}
		return new UserDetailsByNameServiceWrapper(uds);
	}

	/**
	 * Obtains a user details service for use in RememberMeServices etc. Will return a
	 * caching version if available so should not be used for beans which need to separate
	 * the two.
	 */
	private UserDetailsService getUserDetailsService() {
		Map<String, ?> beans = getBeansOfType(CachingUserDetailsService.class);
		if (beans.isEmpty()) {
			beans = getBeansOfType(UserDetailsService.class);
		}
		if (beans.isEmpty()) {
			throw new ApplicationContextException("No UserDetailsService registered.");
		}
		if (beans.size() > 1) {
			throw new ApplicationContextException("More than one UserDetailsService registered. Please "
					+ "use a specific Id reference in <remember-me/> or <x509 /> elements.");
		}
		return (UserDetailsService) beans.values().toArray()[0];
	}

	@Override
	public void setApplicationContext(ApplicationContext beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

	private Map<String, ?> getBeansOfType(Class<?> type) {
		Map<String, ?> beans = this.beanFactory.getBeansOfType(type);
		// Check ancestor bean factories if they exist and the current one has none of the
		// required type
		BeanFactory parent = this.beanFactory.getParentBeanFactory();
		while (parent != null && beans.isEmpty()) {
			if (parent instanceof ListableBeanFactory) {
				beans = ((ListableBeanFactory) parent).getBeansOfType(type);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Specify which service to use: <remember-me service-ref="beanId"/> or <x509 user-service-ref="beanId"/>.
  2. Remove or merge redundant UserDetailsService beans so only one remains.
  3. Qualify one bean as the primary and reference it explicitly in the XML config.

Example fix

// before
<remember-me key="myKey"/>

// after (two uds beans exist)
<remember-me key="myKey" service-ref="jdbcUserService"/>
Defensive patterns

Strategy: validation

Validate before calling

int n = ctx.getBeanNamesForType(UserDetailsService.class).length;
if (n > 1) {
  throw new IllegalStateException("Multiple UserDetailServices; set service-ref explicitly");
}

Try / catch

try { buildContext(); }
catch (ApplicationContextException e) {
  if (e.getMessage().startsWith("More than one UserDetailsService")) promptForExplicitRef();
}

Prevention

When it happens

Trigger: Two or more beans of type UserDetailsService (or CachingUserDetailsService) exist and <remember-me/> or <x509/> is configured without a service-ref/user-service-ref attribute.

Common situations: Adding a second user store (e.g. in-memory for tests alongside JDBC) in the same context; multiple auto-configured UserDetailService sources; Spring Boot devtools restart duplicating 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/bd737246d510cc32. Report an issue: GitHub.