jackc/pgx · error

channel binding required but failed to get server…

Error message

channel binding required but failed to get server certificate hash: %w

What it means

SCRAM channel binding was requested (tls-server-end-point), but the client could not derive a hash of the server certificate — typically because the TLS connection state or certificate is unavailable. The wrapped error identifies the exact cause. The connection attempt is aborted since channel binding cannot proceed.

Solutions

  1. Check the wrapped error for the underlying TLS failure
  2. Set ChannelBinding to "disable" if channel binding is not required
  3. Ensure the connection is actually using TLS before requiring channel binding
  4. Verify the server certificate uses a supported signature algorithm (see RFC 5929)
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at pgconn/auth_scram.go:59 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04). Data as JSON: /api/errors/c658f85f32ffdeec. Report an issue: GitHub.

Appendix: source

Thrown at pgconn/auth_scram.go:59

// Perform SCRAM authentication.
func (c *PgConn) scramAuth(serverAuthMechanisms []string) error {
	sc, err := newScramClient(serverAuthMechanisms, c.config.Password)
	if err != nil {
		return err
	}

	serverHasPlus := slices.Contains(sc.serverAuthMechanisms, scramSHA256PlusName)
	if c.config.ChannelBinding == "require" && !serverHasPlus {
		return errors.New("channel binding required but server does not support SCRAM-SHA-256-PLUS")
	}

	// If we have a TLS connection and channel binding is not disabled, attempt to
	// extract the server certificate hash for tls-server-end-point channel binding.
	if tlsConn, ok := c.conn.(*tls.Conn); ok && c.config.ChannelBinding != "disable" {
		certHash, err := getTLSCertificateHash(tlsConn)
		if err != nil && c.config.ChannelBinding == "require" {
			return fmt.Errorf("channel binding required but failed to get server certificate hash: %w", err)
		}

		// Upgrade to SCRAM-SHA-256-PLUS if we have binding data and the server supports it.
		if certHash != nil && serverHasPlus {
			sc.authMechanism = scramSHA256PlusName
		}

		sc.channelBindingData = certHash
		sc.hasTLS = true
	}

	if c.config.ChannelBinding == "require" && sc.channelBindingData == nil {
		return errors.New("channel binding required but channel binding data is not available")
	}

	// Send client-first-message in a SASLInitialResponse
	saslInitialResponse := &pgproto3.SASLInitialResponse{
		AuthMechanism: sc.authMechanism,

View on GitHub (pinned to ec1a0befd2)