spring-projects/spring-security · error · RuntimeException
user '{username}' does not exist
Error message
user '{username}' does not exist What it means
InMemoryUserDetailsManager.updatePassword looks up the user by lowercased username in its internal users map; if absent it throws a plain RuntimeException stating the user does not exist. Unlike updatePassword in some managers this is not a typed UsernameNotFoundException — it is an unmanaged failure signaling a caller bug or data mismatch, since the user should already have been loaded from this manager.
Source
Thrown at core/src/main/java/org/springframework/security/provisioning/InMemoryUserDetailsManager.java:163
if (this.authenticationManager != null) {
this.logger.debug(LogMessage.format("Reauthenticating user '%s' for password change request.", username));
this.authenticationManager
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated(username, oldPassword));
}
else {
this.logger.debug("No authentication manager set. Password won't be re-checked.");
}
MutableUserDetails user = this.users.get(username.toLowerCase(Locale.ROOT));
Assert.state(user != null, "Current user doesn't exist in database.");
user.setPassword(newPassword);
}
@Override
public UserDetails updatePassword(UserDetails user, @Nullable String newPassword) {
String username = user.getUsername();
MutableUserDetails mutableUser = this.users.get(username.toLowerCase(Locale.ROOT));
if (mutableUser == null) {
throw new RuntimeException("user '" + username + "' does not exist");
}
mutableUser.setPassword(newPassword);
return mutableUser;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = this.users.get(username.toLowerCase(Locale.ROOT));
if (user == null) {
throw UsernameNotFoundException.fromUsername(username);
}
if (user instanceof CredentialsContainer) {
return user;
}
return new User(user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(),
user.isCredentialsNonExpired(), user.isAccountNonLocked(), user.getAuthorities());
}
View on GitHub (pinned to 96852e8860)
Solutions
- Verify the user exists in this same manager before updating: assert userExists(user.getUsername()) is true
- Only pass UserDetails objects that came from this manager's loadUserByUsername/createUser
- Normalize the username (trim/lowercase) to match the manager's keying
- Create the user first (createUser) when the intention is to add-and-set-password
Example fix
// before
manager.updatePassword(userFromOtherService, "new"); // RuntimeException
// after
if (manager.userExists(user.getUsername())) {
manager.updatePassword(user, "new");
} Defensive patterns
Strategy: validation
Validate before calling
if (!manager.userExists(user.getUsername())) {
throw new UsernameNotFoundException("user " + user.getUsername() + " not in this manager");
} Try / catch
try {
return manager.updatePassword(user, newPassword);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().endsWith("does not exist")) {
// create the user or surface a friendly not-found error
} else { throw e; }
} Prevention
- Only pass UserDetails obtained from the same manager instance
- Normalize usernames (trim/lowercase) before manager calls
- Check userExists before update/delete operations on user data
- Avoid mixing multiple UserDetailsService implementations over the same users
When it happens
Trigger: Passing a UserDetails instance that was never created via this manager (e.g., from another UserDetailsService); username case differences that do not lowercase-match a stored key; the user having been deleted (deleteUser) before updatePassword runs; calling updatePassword after changePassword-related flows removed the entry.
Common situations: Application code mixing multiple UserDetailsService implementations; tests constructing UserDetails objects manually then calling updatePassword; race between user deletion and password update in admin tooling.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- AbstractUserDetailsAuthenticationProvider.locked
- AbstractUserDetailsAuthenticationProvider.disabled
- AbstractUserDetailsAuthenticationProvider.expired
- AccountStatusUserDetailsChecker.locked
- JdbcDaoImpl.notFound
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/938b234b085a5cf9.
Report an issue: GitHub.