A PostgreSQL password reset can look complete while the role still receives a legacy verifier if the cluster default writes the wrong hash type. Setting password_encryption to scram-sha-256 before resetting roles makes newly stored database passwords use SCRAM-SHA-256 instead of legacy MD5 hashes.
PostgreSQL chooses the stored password format when CREATE ROLE, ALTER ROLE, or the psql \password command sets a password. The setting does not rewrite existing rows in pg_authid, so the useful proof is both the active password_encryption value and a reset role whose stored verifier starts with SCRAM-SHA-256.
Client authentication rules still control which password method a connection must use. A pg_hba.conf rule set to scram-sha-256 requires a SCRAM-stored password and clients that support SCRAM, while legacy md5 rules can still accept SCRAM-stored passwords during a staged migration. Keep a working local superuser path until affected roles have been reset and remote logins have been tested.
Related: How to configure pg_hba.conf in PostgreSQL
Related: How to secure a PostgreSQL server
Steps to set password encryption method in PostgreSQL:
- Confirm the PostgreSQL server version supports SCRAM-SHA-256 password verifiers.
$ sudo -u postgres psql -Atc "SHOW server_version;" 18.4 (Ubuntu 18.4-0ubuntu0.26.04.1)
SCRAM-SHA-256 password encryption and authentication are available in PostgreSQL 10 and later.
- Check the current password_encryption value.
$ sudo -u postgres psql -Atc "SHOW password_encryption;" scram-sha-256
- Review password-based pg_hba.conf rules before changing authentication methods.
$ sudo -u postgres psql -P pager=off -c "SELECT line_number, type, database, user_name, address, auth_method FROM pg_hba_file_rules WHERE auth_method IN ('md5','scram-sha-256','password') ORDER BY line_number;" line_number | type | database | user_name | address | auth_method -------------+------+---------------+-----------+-----------+--------------- 125 | host | {all} | {all} | 127.0.0.1 | scram-sha-256 127 | host | {all} | {all} | ::1 | scram-sha-256 131 | host | {replication} | {all} | 127.0.0.1 | scram-sha-256 132 | host | {replication} | {all} | ::1 | scram-sha-256 (4 rows)Do not switch a rule to scram-sha-256 while it still covers roles whose passwords are stored as MD5 hashes. Reset those role passwords first or keep a compatible rule during the migration.
- Set the cluster-wide default password encryption method.
$ sudo -u postgres psql -c "ALTER SYSTEM SET password_encryption = 'scram-sha-256';" ALTER SYSTEM
ALTER SYSTEM writes the override to postgresql.auto.conf. If configuration management owns postgresql.conf directly, make the same setting there instead of leaving two competing sources.
- Reload PostgreSQL configuration.
$ sudo -u postgres psql -c "SELECT pg_reload_conf();" pg_reload_conf ---------------- t (1 row)
- Confirm password_encryption is loaded from the expected source.
$ sudo -u postgres psql -Atc "SELECT setting, source FROM pg_settings WHERE name='password_encryption';" scram-sha-256|configuration file
- Reset each role password that must be stored as a SCRAM-SHA-256 verifier.
$ sudo -u postgres psql postgres=# \password appuser Enter new password for user "appuser": Enter it again: postgres=# \q
A password passed directly in a shell command can leak through shell history, process inspection, terminal logs, or ticket transcripts. Use \password or another approved secret-handling path for real credentials.
- Verify the role now stores a SCRAM-SHA-256 password verifier without printing the hash.
$ sudo -u postgres psql -Atc "SELECT rolname, rolpassword LIKE 'SCRAM-SHA-256$%' FROM pg_authid WHERE rolname='appuser';" appuser|t
pg_authid is readable only by superusers. Keep raw password hashes out of tickets, screenshots, and shared transcripts.
- Locate the active pg_hba.conf file if legacy password rules still need to be changed.
$ sudo -u postgres psql -Atc "SHOW hba_file;" /etc/postgresql/18/main/pg_hba.conf
- Edit the affected pg_hba.conf records so reset roles authenticate with scram-sha-256.
$ sudoedit /etc/postgresql/18/main/pg_hba.conf
host appdb appuser 192.0.2.0/24 scram-sha-256
Incorrect pg_hba.conf ordering can lock out remote clients. Keep local shell or console access available until the test login succeeds.
- Reload PostgreSQL after changing pg_hba.conf.
$ sudo -u postgres psql -c "SELECT pg_reload_conf();" pg_reload_conf ---------------- t (1 row)
- Test a TCP login for a reset role through the updated authentication rule.
$ psql -h 127.0.0.1 -U appuser -d postgres -c "\conninfo" Password for user appuser: Connection Information Parameter | Value ----------------------+------------------------ Database | postgres Client User | appuser Host | 127.0.0.1 Server Port | 5432 Protocol Version | 3.0 Password Used | true SSL Connection | true SSL Protocol | TLSv1.3 SSL Cipher | TLS_AES_256_GCM_SHA384 (11 rows)
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.