๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG2026-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)

Solution 1โœ“ Most common cause

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); } }
Solution 2

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(); }
Solution 3

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); } } }
Solution 4

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! }
Solution 5

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

Spring Boot 2.x

Standard BCryptPasswordEncoder behavior.

Spring Boot 3.x

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.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase