micro/go-micro · error
connection pool exhausted
Error message
connection pool exhausted
What it means
ErrPoolExhausted is the sentinel returned by the NATS connection pool when a caller requests a connection and all pooled connections are checked out (the internal connections channel is empty). Pool size is fixed at creation, so concurrency above that limit triggers this error.
Solutions
- Increase the pool size at transport creation to cover peak concurrency
- Ensure every Get has a matching Put, including on error paths (defer put)
- Add retry/backoff around Get to ride out transient exhaustion
- Check for stuck/leaked connections holding the pool indefinitely
Example fix
// before
conn, _ := pool.Get(ctx) // fails under burst
// after
conn, err := pool.Get(ctx)
if errors.Is(err, nats.ErrPoolExhausted) {
time.Sleep(50 * time.Millisecond)
conn, err = pool.Get(ctx)
}
defer pool.Put(conn) Defensive patterns
Strategy: retry
Validate before calling
// limit concurrency to pool size before calling Get
sem := make(chan struct{}, poolSize)
sem <- struct{}{}
defer func() { <-sem }() Try / catch
conn, err := pool.Get(ctx)
if errors.Is(err, nats.ErrPoolExhausted) {
select {
case <-time.After(100 * time.Millisecond):
conn, err = pool.Get(ctx)
case <-ctx.Done():
return ctx.Err()
}
} Prevention
- Always defer pool.Put(conn) immediately after a successful Get
- Size the pool for peak concurrent requests plus headroom
- Add metrics/alerts on pool in-use count
- Use bounded concurrency (semaphores) around pooled calls
When it happens
Trigger: Calling pool.Get() (or Dial when pooling enabled) while every connection in the fixed-size pool is currently borrowed and not yet returned via Put.
Common situations: Burst of concurrent requests exceeding pool size; leaked connections from code paths that Get without Put (error paths, panics); pool sized too small for service concurrency; slow operations holding connections long.
Related errors
- connection pool is closed
- ErrPoolClosed
- ErrPoolExhausted
- invalid connection from pool
- invalid connection from pool
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/f05fc391f255c33e.
Report an issue: GitHub.
Appendix: source
Thrown at transport/nats/pool.go:13
package nats
import (
"errors"
"sync"
"time"
natsp "github.com/nats-io/nats.go"
)
var (
// ErrPoolExhausted is returned when no connections are available in the pool
ErrPoolExhausted = errors.New("connection pool exhausted")
// ErrPoolClosed is returned when trying to use a closed pool
ErrPoolClosed = errors.New("connection pool is closed")
)
// connectionPool manages a pool of NATS connections
type connectionPool struct {
mu sync.RWMutex
connections chan *pooledConnection
factory func() (*natsp.Conn, error)
size int
idleTimeout time.Duration
closed bool
}
// pooledConnection wraps a NATS connection with metadata
type pooledConnection struct {
conn *natsp.Conn
createdAt time.TimeView on GitHub (pinned to 24529f1404)