1. Home
  2. Home
  3. Documentation
  4. Troubleshooting
  5. SCRAM authentication failed
Last reviewed Edit this page on GitHub

SCRAM authentication failed

SCRAM-SHA-256 has been the default password_encryption since PostgreSQL 14 and is the only authentication method on which channel binding works. This page lists the SCRAM and channel-binding failures on that path: what each user-visible error means and which property or server change fixes it.

For the recommended-default posture (sslmode=verify-full, channelBinding=require), see Configure SSL/TLS (in Quick start) .

Reviewed 2026-05-21 against source:ChannelBinding.java:16-43, ScramAuthenticator.java:99-131, SslTest.java:539-575

Raised by ScramAuthenticator.getChannelBindingData when channelBinding=require is combined with sslmode=disable (or any configuration that never negotiates TLS). Channel binding ties the SCRAM exchange to the TLS session; without TLS there is no channel to bind to.

Resolution: pick one or the other.

  • The intended posture is sslmode=verify-full + channelBinding=require. This is the combination Configure SSL/TLS (in Quick start) recommends, and the only one that defends against an attacker who can terminate-and-replay the TLS handshake.
  • If TLS is genuinely impossible (a local Unix-domain socket bridge, a closed dev loop) drop channel binding too: channelBinding=prefer or disable.

Reviewed 2026-05-21 against source:ScramAuthenticator.java:75-96

The server selected SASL/SCRAM, but the SASL mechanism list did not include a -PLUS mechanism. pgJDBC raises this after it receives AuthenticationSASL and finds no advertised mechanism whose name ends with -PLUS.

The usual cause is an older server that supports SCRAM-SHA-256 but not SCRAM-SHA-256-PLUS. Channel binding needs the scram-sha-256-plus SASL mechanism, added in PostgreSQL 11. On older servers, use channelBinding=prefer until you can upgrade.

Reviewed 2026-05-21 against source:ConnectionFactoryImpl.java:758-779, ConnectionFactoryImpl.java:845-859, SslTest.java:578-593

With channelBinding=require, pgJDBC rejects any non-SASL authentication request before responding to it. The method name in the message is whatever the server selected: md5, password, gss, sspi, or a numeric code for an unsupported method.

Common causes:

  • pg_hba.conf matched a non-SCRAM rule. Reorder or replace the matching rule so this client uses hostssl ... scram-sha-256.

  • The user is stored with MD5 password encryption and pg_hba.conf matched md5. Re-set the user password while password_encryption = scram-sha-256 is in effect in postgresql.conf (the default since PostgreSQL 14):

    ALTER USER alice WITH PASSWORD 'plaintext';  -- gets stored as scram-sha-256
    

    \\password in psql works too. Confirm with:

    SELECT rolname, rolpassword FROM pg_authid WHERE rolname = 'alice';
    

    The value should start with SCRAM-SHA-256$.

Reviewed 2026-05-21 against source:ConnectionFactoryImpl.java:845-859

The server accepted the connection without running SCRAM, usually because the matching pg_hba.conf rule uses trust. Channel binding can only be completed after a SCRAM-SHA-256-PLUS exchange, so pgJDBC rejects this before the connection is handed back to the application.

Resolution: replace or reorder the matching trust rule so this client uses hostssl ... scram-sha-256. If you intentionally rely on trust for a closed local development loop, set channelBinding=prefer or disable for that connection.

Reviewed 2026-05-21 against source:ScramAuthenticator.java:99-131

The TLS handshake succeeded, but pgJDBC could not read or encode the peer certificate from the JSSE session while building the tls-server-end-point binding. In current code this message is raised when SSLSession.getPeerCertificates() reports an unverified peer or when the peer certificate cannot be encoded.

This normally points at the TLS socket/session implementation rather than a pgJDBC property. Inspect a custom SSLSocketFactory first; the stock org.postgresql.ssl.LibPQFactory is expected to expose the server’s X.509 certificate.

There is no client-side property to bypass: channel binding cannot work without a server certificate.

Reviewed 2026-05-21 against source:PGProperty.java:835-850, ConnectionFactoryImpl.java:997-1021, ScramAuthenticator.java:151-171, ScramTest.java:126-195

A safety cap. pgJDBC accepts at most scramMaxIterations PBKDF2 rounds from the server (default 100,000); higher counts are rejected before the expensive PBKDF2 computation runs. Without the cap, a malicious or compromised server could force the client to burn CPU on an attacker-controlled iteration count.

Resolution depends on context:

  • You trust the server and it legitimately uses a high count. Raise scramMaxIterations . Set to 0 to disable the check entirely (not recommended).
  • You do not trust the server. Do not raise the limit; the default is the protection, not the problem.

Reviewed 2026-05-21 against source:PGProperty.java:807-821, AuthMethod.java:34-75, ConnectionFactoryImpl.java:794-798, ConnectionFactoryImpl.java:864-1042, RequireAuthTest.java:129-210

You configured an explicit allow-list of authentication methods via requireAuth and the server offered something else. The property accepts a comma-separated list of password, md5, gss, sspi, scram-sha-256, none, with a ! prefix for negative entries (requireAuth=!password,!md5 forbids cleartext and MD5).

Resolution:

  • Add the offered method to the list, if it was an oversight.
  • Fix the server. If the server offers md5 and you wrote requireAuth=scram-sha-256, the password is stored under a weaker scheme. Migrate to SCRAM (see the first case above).

The error fires before authentication completes, so no credentials are ever sent under the unwanted method.

NameTypeDefaultVersionsDescription
authenticationPluginClassNameclass
  • since 42.2.25
Name of class which implements AuthenticationPlugin
channelBindingenumprefer
  • since 42.7.0
This option controls the client’s use of channel binding.
passwordstring
  • since 9.4
Password to use when authenticating.
requireAuthstring
  • since 42.7.0
Comma-separated list of acceptable authentication methods. Use ‘!’ prefix to reject methods (e.g., ‘!password’ to reject cleartext). Supported: password, md5, gss, sspi, scram-sha-256, none
scramMaxIterationsint100000
  • since 42.7.11
Maximum PBKDF2 iteration count accepted from the server during SCRAM authentication. A value of zero disables this check.
userstring
  • since 9.4
Username to connect to the database as.
  • Authentication : the conceptual companion to this page covers which methods the driver supports, how the server-driven negotiation resolves, and the levers (requireAuth, channelBinding, scramMaxIterations, AuthenticationPlugin) that bound it.
  • Configure SSL/TLS (in Quick start) : the recommended-default combination of sslmode=verify-full, sslrootcert, and channelBinding=require.
  • SSL / TLS connection errors : failure modes on the TLS layer underneath SCRAM. Channel binding cannot succeed if the TLS handshake itself doesn’t.
  • Compatibility : channel binding requires PostgreSQL 11+; SCRAM-SHA-256 is the default password encoding from PG 14.