LoadType during AfterConnect fails with context timeout leading to queries failing
- Dominant language
- Go
- Stars
- 14.3k
- Forks
- 1.1k
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 11
Description
**Describe the bug**
I haven't been able to fully figure out what is happening here, so this will probably be a bit unclear. Sorry. There might even be two issues interacting here.
We setup our pgxpool to have an AfterConnect function. This function calls LoadTypes on the connection to prepare it for use. Frequently LoadTypes is resulting in a context timeout and disconnecting from the postgres server. However, it seems like this doesn't always surface to caller and then leads to queries failing with "failed to deallocate cached statement(s): conn closed".
**To Reproduce**
Unfortunately, I can't really provide a repro case as it's not deterministic. I was able to get this to trigger while running with the race detector enabled and it didn't detect any issues. I setup pgx with a `tracelog.TraceLog` at TraceLevel and also enabled tracing of the front end with `conn.PgConn().Frontend().Trace`. Attached is a log from when this occurred. In prior debugging attempts I examined the context passed to the AfterConnect function. It had ~1m10s left till it timed out and the actual call only took ~63ms before the context timeout occurred.
[pgx-trace.log](https://github.com/user-attachments/files/27213493/pgx-trace.log)
You can see the first error on line 14659 or by searching for "time="2026-04-29T17:33:47Z" level=error".
**Expected behavior**
LoadTypes succeeds when there is a connection to the database.
Failures in AfterConnect / LoadType don't result in top level pgx calls such as `err := pool.SendBatch(ctx, batch).Close()` connection closed error when there is no underlying problems preventing connection.
**Actual behavior**
Queries return `failed to deallocate cached statement(s): conn closed` sometimes and some connection attempts fail.
**Version**
- Go: go version go1.26.2 linux/amd64
- PostgreSQL: PostgreSQL 17.9 (Debian 17.9-1.pgdg13+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
- pgx: github.com/jackc/pgx/v5 v5.9.2
**Additional context**
The behavior occurs even when run locally. On a single machine there is a primary database and an asynchronous streaming replica. There are two pgbouncer instances running, one for each database. All connections are made through pgbouncer in transaction mode.
The behavior seems somewhat timing dependent. Running go test with `-v` reduces the frequency with which problems occur. I was only able to get it to occur with pgx logs enabled by logging to memory and then writing it to a file at the end. However, the race detector found no issues.
In pgx 5.8.0, the error in LoadTypes was correctly reported and handled by the pool. The subsequent failures didn't occur. After upgrading to 5.9.2, I don't believe I've seen AfterConnect report LoadTypes failed. However, it may have while running with less verbosity. In 5.9.2 other queries failing trying to deallocate prepared statements on a close connection.
We perform no manual Acquire calls. All queries are through the pool (or a txn from the pool). In the test there are three pool instances. One to the primary, and then for read-only calls one to the primary with `default_transaction_read_only` set to on and one to the replica.
The pgbouncer logs show the client disconnecting during the query, which matches the context timeout error from pgx.
```
2026-04-29 17:33:47 UTC [575-3] service_user@pastegres LOG: could not send data to client: Broken pipe
2026-04-29 17:33:47 UTC [575-4] service_user@pastegres STATEMENT:
WITH RECURSIVE
-- find the OIDs in pg_class which match one of the provided type names
2026-04-29 17:33:47 UTC [575-5] service_user@pastegres FATAL: connection to client lost
```
While I can't provide the code in full, I can share pieces as relevant as well as logs from postgres. I can also try any suggestions or additional logging to help understand this issue.
Thanks!
Contributor guide
Research direction
Start with the pool's AfterConnect path and LoadTypes, using the attached pgx trace around line 14659 and the pgbouncer log as the failure timeline. Compare the reported behavior between pgx v5.8.0 and v5.9.2, including pool.SendBatch(ctx, batch).Close() and connection cleanup. Done means LoadTypes failures are reported and handled consistently without unrelated top-level queries returning connection-closed errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgresql
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100