micro/go-micro · error
ErrPoolClosed
ErrPoolClosed
Error message
connection pool is closed
What it means
ErrPoolClosed is a sentinel error returned by pool.Get(), TestConnectionPool_Close, and TestTransportConnectionPool_Close when an operation attempts to acquire a connection from a pool that has already been closed. Once Close() is called the pool stops handing out connections permanently.
Source
Thrown at broker/nats/pool.go:15
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.Time
lastUsed time.Time
mu sync.MutexView on GitHub (pinned to 24529f1404)
Solutions
- Call broker.Connect again to recreate the pool before subscribing after a Disconnect.
- Fix lifecycle ordering: stop all consumers before closing the broker.
- Check the broker's connection state before use in long-running services.
Example fix
// before
b.Disconnect()
sub, _ := b.Subscribe("events", handler) // ErrPoolClosed
// after
b.Disconnect()
if err := b.Connect(); err != nil { return err }
sub, _ := b.Subscribe("events", handler) Defensive patterns
Strategy: validation
Validate before calling
if err == natsbroker.ErrPoolClosed {
// pool was closed; reconnect before subscribing
} Try / catch
sub, err := b.Subscribe(topic, handler)
if errors.Is(err, natsbroker.ErrPoolClosed) {
if cerr := b.Connect(); cerr != nil { return cerr }
sub, err = b.Subscribe(topic, handler)
} Prevention
- Enforce lifecycle ordering: close the pool only after all consumers stop.
- Track a 'running' flag and reject work after Disconnect.
- Never reuse a broker instance after teardown without reconnecting.
When it happens
Trigger: Calling Subscribe (which does pool.Get()) after broker.Disconnect/Close has closed the connection pool; reusing a broker instance after shutdown.
Common situations: Lifecycle ordering bugs — a shutdown handler closes the broker while background workers still try to subscribe/publish; reusing a cached broker client after application teardown.
Related errors
- ErrPoolExhausted
- connection pool is closed
- invalid connection from pool
- invalid connection from pool
- connection pool exhausted
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/ca1f64b41a96c994.
Report an issue: GitHub.