PostgreSQL 18 MD5 Password Deprecation: How to Move to SCRAM
PostgreSQL 18 deprecates MD5-encrypted passwords; here is how to audit roles, move to SCRAM-SHA-256, and avoid surprise login failures.
PostgreSQL 18 adds another clear signal that MD5 password authentication is on the way out. The release notes say MD5 password authentication is deprecated and that support for MD5 passwords will be removed in a future major version. The documentation for pg_hba.conf and pg_authid now carries the same warning for MD5-encrypted passwords.
That does not mean every PostgreSQL 18 upgrade breaks old logins immediately. It does mean that production teams should stop treating MD5 as a harmless legacy default. If a role still stores an MD5 password hash, the safe path is to rotate it to SCRAM-SHA-256 before the removal becomes a deadline.
What changed in PostgreSQL 18
The practical change is a deprecation notice, not a sudden removal. PostgreSQL still documents the md5 authentication method, but it warns that support for MD5-encrypted passwords is deprecated and will be removed in a future release. The password authentication docs also describe why: the custom MD5 challenge-response method is weaker, the MD5 hash algorithm is no longer considered secure against determined attacks, and a stolen MD5 password hash is more useful to an attacker than a modern SCRAM verifier.
There is one transition detail worth understanding. PostgreSQL can automatically use SCRAM when md5 appears in pg_hba.conf if the user's stored password is already a SCRAM-SHA-256 verifier. In other words, the most important first step is often not editing every access rule. It is making sure roles no longer have stored passwords that begin with the old MD5 format.
Why managed PostgreSQL users should care
Authentication debt tends to hide because the application still connects successfully. A service account created years ago may keep working through a pooler, a migration job, or a rarely used admin script. The risk appears later, when a major-version upgrade, provider policy, security audit, or client-library cleanup forces the team to examine the password format under time pressure.
For managed PostgreSQL, the database provider may control parts of pg_hba.conf, network exposure, TLS, and password policy. The application team still owns user rotation, connection strings, deployment secrets, and client compatibility. That split is exactly why this deprecation deserves a planned migration rather than a rushed incident response.
| Area to check | What to look for | Recommended action |
|---|---|---|
| Stored role passwords | Entries in pg_authid.rolpassword that start with md5 | Rotate those role passwords after setting SCRAM as the password encryption method |
| Access rules | pg_hba.conf lines that name md5 explicitly | Prefer scram-sha-256 where you control the rule, after client compatibility is verified |
| Application clients | Old drivers, base images, or language runtimes | Test SCRAM login from every production client path before cutting over |
| Secrets management | Passwords copied across staging, jobs, and local tools | Rotate through the normal secret store, not ad hoc SQL pasted into terminals |
| Poolers and proxies | PgBouncer or sidecar settings that authenticate users | Confirm how the pooler stores or validates user credentials during the rotation |
How to audit and migrate
Start by inventorying login roles. PostgreSQL stores role passwords in the pg_authid catalog, which is only readable by sufficiently privileged users. On self-managed systems, a superuser can check the password format directly. On managed services, the provider may expose a safer administrative view or require support tooling; if direct catalog access is restricted, rotate all application roles instead of trying to inspect forbidden metadata.
A direct audit usually looks for the prefix documented in pg_authid: MD5-encrypted passwords begin with md5, while SCRAM verifiers use the SCRAM-SHA-256$... format. Treat the query output as sensitive operational metadata, and avoid exporting it to tickets or logs.
For each affected role, set password_encryption to scram-sha-256 for the session that performs the rotation, then run ALTER ROLE ... PASSWORD ... with a newly generated secret. Update the application secret store, deploy the new value, and verify a fresh connection before removing the old credential from any fallback location. The exact SQL is simple, but the rollout should follow your normal production secret-change process.
If you control pg_hba.conf, change authentication rules deliberately. The PostgreSQL docs explain that a rule written as md5 can still negotiate SCRAM for roles that already have SCRAM passwords, which can be useful during migration. Once the clients are verified, a rule that explicitly says scram-sha-256 is clearer and prevents a new MD5-only role from becoming part of the path again.
Common failure modes
The most common mistake is rotating the database role before checking every client path. The web app may use a modern driver, while a queue worker, data import script, or old migration container still ships a client library that cannot authenticate with SCRAM. Test from the same runtime images that production uses, not just from a laptop with a current psql binary.
Another failure mode is missing pooler behavior. PgBouncer deployments can authenticate clients independently from the server connection. Depending on configuration, you may need to update a userlist, auth query, or secret mount as part of the same change. If the pooler keeps using an old credential while the server role has changed, the symptom can look like a PostgreSQL login failure even though the application secret was updated correctly.
Finally, do not use this migration as an excuse to weaken network or TLS controls. SCRAM improves password authentication, but it does not replace encrypted connections, least-privilege roles, short-lived incident credentials, or a clean way to revoke access when a teammate or vendor leaves.
What to do now
If you are planning a PostgreSQL 18 adoption cycle, add MD5 password removal to the same checklist as extension compatibility, backup validation, and client-driver testing. The work is small when done role by role, and painful when discovered during a blocked upgrade.
ArmorDB users should treat application role rotation as part of routine managed PostgreSQL hygiene: use separate roles per environment, keep credentials in deployment secrets, and validate connection behavior through the same path the application uses in production. For broader upgrade planning, the PostgreSQL 18 release notes are worth reading before the first staging cutover.
Sources and further reading
Topic
Tech-News & Trends
Updated
Jul 5, 2026
Read time
6 min read
ArmorDB Engineering writes about PostgreSQL operations, security, and infrastructure decisions for teams building production apps on ArmorDB.
Read next
Data-Specs / Vergleiche · 7 min read
PostgreSQL Encryption Options Compared: TLS, Disk, and Field-Level Controls
Compare PostgreSQL encryption in transit, encryption at rest, pgcrypto, and application-level encryption so you can choose the right control for each risk.
Read articleShort-Form & Quick Fixes · 5 min read
How to Fix PostgreSQL Permission Denied for Schema Public
Learn why PostgreSQL returns permission denied for schema public, how to grant the right schema and table privileges, and how to avoid insecure blanket grants.
Read article