Compatibility guide
WordPress password hash formats, without the guesswork.
Use the prefix to identify the format, then choose the right recovery or migration path. This is a practical reference for the values you find in user_pass.
$wp$2y$.They are bcrypt hashes with WordPress’s SHA-384 pre-hash and a $wp marker.
$P$ hashes are still valid.WordPress keeps phpass support so an upgrade does not lock users out.
Plugins can use their own hashing logic, so always consider the site’s configuration.
What lives in user_pass?
WordPress does not store a reversible password. It stores a one-way value that can be checked when someone signs in. The same password will normally produce different stored values because password-hashing algorithms include a random salt. Treat both the password and its hash as sensitive: neither belongs in a ticket, screenshot, or public repository.
The beginning of the stored string is the quickest way to identify the normal verification path. The matrix below describes the formats you are most likely to encounter in a WordPress database.
$wp$2y$Current WordPress Core bcrypt formatUse the modern generator or let WordPress create it.$P$Legacy portable phpassStill accepted; use only for a legacy-compatible reset.$2y$ / $2b$Plain bcrypt, often plugin-createdVerify as normal bcrypt; do not add $wp yourself.32 hex charsLegacy MD5An emergency fallback; change the password after signing in.$argon2id$Argon2, opt-in via a filterNot created by default; confirm the site enabled it before assuming.Current WordPress: why $wp$2y$ is not plain bcrypt
WordPress 6.8 made bcrypt the default for new user passwords. To preserve the full entropy of passwords longer than bcrypt’s 72-byte input limit, Core first creates a keyed SHA-384 HMAC and Base64-encodes it. It then bcrypts that resulting value and adds the $wp prefix. A deeper look at the stored value lives in why a hash starts with $wp$2y$.
This matters when a database value must be set manually: a plain $2y$ bcrypt hash is not the same as a current Core-created password hash. The modern hash generator follows this sequence and produces the stored $wp$2y$ value.
Legacy phpass: $P$
Before 6.8, WordPress’s standard password hasher produced a portable phpass value, usually beginning $P$. WordPress continues to verify these values so existing users can sign in after an upgrade. Once they change their password or log in under the current default flow, WordPress can replace the old value with a newer hash.
Use the legacy phpass generator when you know the target needs this format—for example, an older installation or a migration procedure that explicitly requires it. Do not choose it simply because it is familiar.
Plain bcrypt, MD5, and custom algorithms
A hash beginning $2a$, $2b$, or $2y$ is ordinary bcrypt without the WordPress $wp envelope. This can be legitimate when a plugin or integration generated the password. A 32-character hexadecimal value is commonly an old MD5 value; WordPress retains MD5 checking for backward compatibility, but it should be replaced after access is restored.
WordPress installations can also opt into another supported password algorithm, such as Argon2, or replace password handling through a plugin. That is why a prefix helps with identification but does not eliminate the need to understand the target site.
Before you paste a hash into a database
- Confirm that you are authorized to administer the site and have a current backup.
- Identify the WordPress version or expected format instead of guessing from a tutorial.
- Use the normal reset flow or WP-CLI when available; let WordPress create the value itself.
- Use the local verifier to test a hash only when necessary, then change the password through WordPress after recovery.
Quick answers
Is phpass ($P$) deprecated in WordPress?
It is no longer the default as of 6.8, but it is not removed. wp_check_password() still verifies $P$ hashes indefinitely, and a matching account is silently rehashed to $wp$2y$ the next time it logs in successfully.
Can I convert a hash from one format to another directly?
No. A hash cannot be converted without knowing the original password, because hashing is one-way. The only way to move an account to a new format is a normal password change or reset, which lets WordPress hash the new value itself.
What's the difference between $2y$ and $2b$?
Both are bcrypt version identifiers; $2b$ fixed an obscure edge case in how some implementations handled passwords over 255 bytes, but for ordinary WordPress passwords the two verify identically. Neither is the same as $wp$2y$, which adds a pre-hash step Core-plain bcrypt libraries don't perform.
Does WordPress ever use Argon2 by default?
No. Argon2 support exists behind a filter a site or plugin must explicitly enable; a stock WordPress install never produces an $argon2id$ hash on its own.
Primary references: wp_hash_password() and wp_check_password().