jackc/pgx · error

pgxpool: too many failed attempts acquiring connection…

Error message

pgxpool: too many failed attempts acquiring connection; likely bug in PrepareConn, BeforeAcquire, or ShouldPing hook

What it means

Pool.Acquire loop-exhaustion error: every acquisition attempt in this call failed its post-connect hook (BeforeAcquire, ShouldPing, or PrepareConn returned not-ok) until the attempt budget ran out. As the message states, this nearly always means one of those user-supplied hooks is buggy and rejects every connection — e.g. a PrepareConn that always errors.

Solutions

  1. Log and fix the error returned by PrepareConn/BeforeAcquire/ShouldPing so healthy connections pass
  2. Check that the hooks' SQL/settings are valid on the target server
  3. Remove the hook temporarily to confirm it is the culprit
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pgxpool/pool.go:668 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at pgxpool/pool.go:668

		if p.prepareConn != nil {
			ok, err := p.prepareConn(ctx, cr.conn)
			if !ok {
				res.Destroy()
			}
			if err != nil {
				if ok {
					res.Release()
				}
				return nil, err
			}
			if !ok {
				continue
			}
		}

		return cr.getConn(p, res), nil
	}
	return nil, errors.New("pgxpool: too many failed attempts acquiring connection; likely bug in PrepareConn, BeforeAcquire, or ShouldPing hook")
}

// AcquireFunc acquires a [Conn] and calls f with that [Conn]. ctx will only affect the [Pool.Acquire]. It has no effect on the
// call of f. The return value is either an error acquiring the [Conn] or the return value of f. The [Conn] is
// automatically released after the call of f.
func (p *Pool) AcquireFunc(ctx context.Context, f func(*Conn) error) error {
	conn, err := p.Acquire(ctx)
	if err != nil {
		return err
	}
	defer conn.Release()

	return f(conn)
}

// AcquireAllIdle atomically acquires all currently idle connections. Its intended use is for health check and
// keep-alive functionality. It does not update pool statistics.
func (p *Pool) AcquireAllIdle(ctx context.Context) []*Conn {

View on GitHub (pinned to ec1a0befd2)