jackc/pgx · error

cannot hijack already released or hijacked connection

Error message

cannot hijack already released or hijacked connection

What it means

Conn.Hijack panics when the handle's internal resource is nil — i.e. the pooled connection was already Release()d or previously Hijack()ed — because there is no underlying connection left to transfer ownership of.

Solutions

  1. Call Hijack exactly once per acquired connection and only before Release
  2. Track hijacked/released state in calling code so a spent handle is never reused
  3. Acquire a fresh connection from the pool instead of reusing a spent handle
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pgxpool/conn.go:73 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/2df9ede52684a07e. Report an issue: GitHub.

Appendix: source

Thrown at pgxpool/conn.go:73

	}

	go func() {
		if c.p.afterRelease(conn) {
			res.Release()
		} else {
			res.Destroy()
			// Signal to the health check to run since we just destroyed a connections
			// and we might be below minConns now
			c.p.triggerHealthCheck()
		}
	}()
}

// Hijack assumes ownership of the connection from the pool. Caller is responsible for closing the connection. Hijack
// will panic if called on an already released or hijacked connection.
func (c *Conn) Hijack() *pgx.Conn {
	if c.res == nil {
		panic("cannot hijack already released or hijacked connection")
	}

	conn := c.Conn()
	res := c.res
	c.res = nil

	res.Hijack()

	return conn
}

func (c *Conn) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error) {
	return c.Conn().Exec(ctx, sql, arguments...)
}

func (c *Conn) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) {
	return c.Conn().Query(ctx, sql, args...)
}

View on GitHub (pinned to ec1a0befd2)