Encoded password does not look like BCrypt
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
The error saying an encoded password does not look like BCrypt usually means your application is trying to verify a password with a BCrypt-based encoder while the stored value is in some other format. That mismatch often appears during migrations, after framework upgrades, or when one password-writing code path forgot to use the shared encoder. The fix is not just swapping one class for another. You also need a clear policy for the hashes that are already in the database.
What Spring Security Is Expecting
BCryptPasswordEncoder expects a BCrypt-formatted hash. Those strings usually start with markers such as , , or a framework-specific prefix when a delegating encoder is in use.
If the value in the database is plain text, SHA-based, or stored with the wrong prefixing rules, the matcher has nothing valid to work with and fails immediately.
Audit the Data Before Changing Code
The most productive next step is usually a data audit. Find out how many rows are actually BCrypt, how many use a legacy format, and whether some records are plain text due to a broken write path.
That query gives you an estimate of the migration problem. Without it, teams often change encoder configuration blindly and still do not know whether the database is getting healthier or worse.
Prefer a Delegating Encoder for Mixed Environments
If your application may see more than one password format during a transition, DelegatingPasswordEncoder is the safer choice. It makes the algorithm explicit by storing a prefix with each value.
That prefix-driven routing is much clearer than guessing which algorithm to apply based on string shape or historical assumptions.
Check Every Password-Writing Path
Many teams fix the login matcher and forget the real root cause: one flow is still saving passwords incorrectly. Audit all paths that create or update password hashes:
- Registration.
- Password reset.
- Admin user creation.
- Bulk imports.
- Test fixtures and seed scripts.
Any one of those can keep injecting bad data into the table even after the login path is corrected. Security bugs persist when write paths are inconsistent.
Plan the Migration Strategy
There are usually two practical migration options:
- Force resets for users with non-BCrypt values.
- Verify legacy hashes temporarily, then re-hash with the current encoder after successful login.
The second option reduces friction, but it must be time-boxed. Temporary support has a habit of becoming permanent if nobody tracks the number of remaining legacy hashes. If you keep the fallback path, instrument it so you know exactly how many successful logins still depend on the legacy format.
A good migration plan includes metrics, deadlines, and one clear owner for removing the fallback path.
Centralize Encoder Configuration
Password handling becomes fragile when different components construct their own encoders. Put the password encoder in one configuration bean and inject it everywhere password values are written or checked.
This makes policy changes visible and keeps test code aligned with production behavior.
Test the Whole Password Lifecycle
Unit tests are not enough here. You want integration tests that prove registration stores the expected format, login can verify it, and password reset does not bypass the encoder.
If a migration path exists, test that too. A password-migration bug is easy to miss because users do not all hit the same path on the same day. Good tests keep the old and new behavior explicit until the transition is complete.
Common Pitfalls
The biggest mistake is assuming the error is only a login issue when the real problem is bad stored data. Another is enabling temporary legacy support with no removal plan. Teams also get into trouble by using multiple encoder instances with different policies, trimming or altering stored hash strings in the database layer, or forgetting to audit all password-writing workflows after a migration.
Summary
- The error means the stored password format does not match the active verifier.
- Audit the database before changing encoder configuration.
- Prefer a delegating encoder when multiple formats may exist during migration.
- Check every code path that writes password hashes.
- Treat legacy-format support as a migration phase with metrics and an end date.
Related reading
- Encrypt and decrypt a string in C?
- Encrypt and decrypt using PyCrypto AES-256
- Encrypting the Hadoop Distributed Cache file
- Enforce MFA for AWS console login but not for API calls
- endpoints “default-http-backend” not found in Ingress resource
- Ensure that AMQP exchange exists before publishing a message to it
- Error certificate signed by unknown authority after switching GCP project
- Error reading service account token from /var/run/secrets/kubernetes.io/serviceaccount/token. Ignoring

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.