๐ด The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
2026-02-19 09:10:15.123 ERROR 8842 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: Encoded password does not look like BCrypt] with root cause
java.lang.IllegalArgumentException: Encoded password does not look like BCrypt
at org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder.upgradeEncoding(BCryptPasswordEncoder.java:184)โก Quick Fix Works 80% of the time
Ensure you hash the password using passwordEncoder.encode() before saving it to the database.
public void register(User user) {
String rawPassword = user.getPassword();
String hashedPassword = passwordEncoder.encode(rawPassword);
user.setPassword(hashedPassword);
repo.save(user);
}๐ง Why this Happens
Tap to expand the deep technical explanation
You configured a `BCryptPasswordEncoder` in your Spring Security config. When a user tries to log in, Spring fetches the stored password from the database and attempts to match it against the entered password. However, the stored password is plain text (or encoded with a different algorithm), so BCrypt rejects it because it doesn't start with the expected `$2a$` hash format.
The HITEC City Parking Spot Analogy:
It's like trying to unlock a digital safe (BCrypt), but you stored a physical metal key (plain text) in the database. The safe doesn't know what to do with the metal key and throws an error.
๐ How to Reproduce Confirm this is your error
Create a user in your database with the password stored as plain text (e.g., `password123`). Configure a `BCryptPasswordEncoder` bean. Attempt to log in with that user.
๐ ๏ธ Solutions (5 Ways to Fix)
Hash passwords before saving to DB
๐ Use this if your database contains plain text passwords.
Always use the PasswordEncoder to hash passwords during the user registration process, never saving the raw string.
@Service
public class RegistrationService {
@Autowired
private PasswordEncoder passwordEncoder;
public void register(UserRequest req) {
User user = new User();
user.setUsername(req.getUsername());
user.setPassword(passwordEncoder.encode(req.getPassword())); // Hash it!
repo.save(user);
}
}Use DelegatingPasswordEncoder (Multi-Algorithm Support)
๐ Use this if you are migrating from an older system with SHA256 or MD5 hashes.
This encoder allows you to store passwords with different algorithms by prefixing the hash (e.g., `{bcrypt}$2a$10$...`).
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}Manually update existing DB records
๐ Use this to fix the bad data already in your database.
Write a SQL script or an initialization bean to encode all existing plain text passwords once.
@PostConstruct
public void fixPasswords() {
List<User> users = repo.findAll();
for (User u : users) {
if (!u.getPassword().startsWith("$2a$")) {
u.setPassword(passwordEncoder.encode(u.getPassword()));
repo.save(u);
}
}
}Use NoOpPasswordEncoder (Testing ONLY)
๐ Use this ONLY for quick local testing. Never use in production.
If you absolutely must use plain text passwords for a prototype, use NoOpPasswordEncoder which does no hashing.
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // UNSAFE!
}Check for accidental double-encoding
๐ Use this if you are hashing on registration, but the hash still looks wrong.
Ensure you aren't accidentally calling `.encode()` twice on the same password before saving, which corrupts the hash.
// BAD
// String pass = passwordEncoder.encode(req.getPassword());
// user.setPassword(passwordEncoder.encode(pass));
// GOOD
user.setPassword(passwordEncoder.encode(req.getPassword()));๐ Version Notes
Standard BCryptPasswordEncoder behavior.
Identical behavior, but requires explicit PasswordEncoder bean definition in SecurityFilterChain.
๐ก๏ธ How to Prevent This Next Time
Always use Constructor Injection to inject the PasswordEncoder into your registration service, ensuring you cannot accidentally bypass the hashing step.