spring-projects/spring-security · error · ApplicationContextException
Bean '{name}' must be a UserDetailsService or an Authenticat
Error message
Bean '{name}' must be a UserDetailsService or an AuthenticationUserDetailsService What it means
UserDetailsServiceFactoryBean.authenticationUserDetailsService() resolves a bean reference into a UserDetailsService wrapper for remember-me/x509 support. After the bean is fetched, it must be an AuthenticationUserDetailsService or a UserDetailsService (or CachingUserDetailsService factory product). If the referenced bean is neither, an ApplicationContextException is thrown because no UserDetails lookup strategy can be derived from it.
Source
Thrown at config/src/main/java/org/springframework/security/config/http/UserDetailsServiceFactoryBean.java:90
+ " Please use a specific Id reference.");
}
return (AuthenticationUserDetailsService) beans.values().toArray()[0];
}
uds = getUserDetailsService();
}
else {
Object bean = this.beanFactory.getBean(name);
if (bean instanceof AuthenticationUserDetailsService) {
return (AuthenticationUserDetailsService) bean;
}
else if (bean instanceof UserDetailsService) {
uds = cachingUserDetailsService(name);
if (uds == null) {
uds = (UserDetailsService) bean;
}
}
else {
throw new ApplicationContextException(
"Bean '" + name + "' must be a UserDetailsService or an" + " AuthenticationUserDetailsService");
}
}
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.");View on GitHub (pinned to 96852e8860)
Solutions
- Make the referenced bean implement org.springframework.security.core.userdetails.UserDetailsService (loadUserByUsername) or AuthenticationUserDetailsService.
- Point service-ref at an existing UserDetailsService bean instead of the wrong bean.
- If the bean is a CachingUserDetailsService produced by a factory, ensure the factory-bean type is correctly declared so it is recognized as a UserDetailsService.
Example fix
// before <bean id="userService" class="com.app.UserService"/> <remember-me service-ref="userService"/> // after <bean id="userService" class="com.app.UserService"/> <bean id="uds" class="com.app.CustomUserDetailsService"/> <remember-me service-ref="uds"/>
Defensive patterns
Strategy: type-guard
Validate before calling
Object bean = ctx.getBean(refName);
if (!(bean instanceof UserDetailsService) && !(bean instanceof AuthenticationUserDetailsService)) {
throw new IllegalArgumentException(refName + " must be a UserDetailsService");
} Type guard
function isUds(Object b) {
return b instanceof org.springframework.security.core.userdetails.UserDetailsService
|| b instanceof org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
} Try / catch
try { svc = factory.authenticationUserDetailsService(refName); }
catch (ApplicationContextException e) { log.error("Bean {} is not a UserDetailsService", refName, e); } Prevention
- Only point service-ref at beans implementing UserDetailsService
- Add an integration test that boots the full security config
- Check bean types in context startup validation
When it happens
Trigger: An <http> remember-me service-ref or x509 service-ref points at a bean whose type is neither UserDetailsService nor AuthenticationUserDetailsService — e.g. referencing a plain DAO, a service class, or a bean typed Object/generic.
Common situations: Typo'd bean id that resolves to the wrong bean; refactoring moved UserDetails logic into a wrapper class no longer implementing UserDetailsService; using an XML ref to a @Component that doesn't implement the interface.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No UserDetailsService registered.
- More than one UserDetailsService registered. Please use a sp
- No id supplied and another bean is already registered as {Be
- No BaseLdapPathContextSource instances found. Have you added
- More than one BaseLdapPathContextSource instance found. Plea
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/da75ef984e78bcb8.
Report an issue: GitHub.