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

  1. Verify the user exists in this same manager before updating: assert userExists(user.getUsername()) is true
  2. Only pass UserDetails objects that came from this manager's loadUserByUsername/createUser
  3. Normalize the username (trim/lowercase) to match the manager's keying
  4. 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

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


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