redis/go-redis · critical
redis: failed to create pipeline connection pool: %w
Error message
redis: failed to create pipeline connection pool: %w
What it means
Panics when building the dedicated pipeline connection pool fails. This pool is optional: it is only created when PipelinePoolSize >= 0, and its construction failure means invalid pool options. The panic aborts NewClient since pipeline behavior would be inconsistent.
Source
Thrown at redis.go:2132
c.connPool, err = newConnPool(opt, c.dialHook, mainPoolName)
if err != nil {
panic(fmt.Errorf("redis: failed to create connection pool: %w", err))
}
c.pubSubPool, err = newPubSubPool(opt, c.dialHook, pubsubPoolName)
if err != nil {
panic(fmt.Errorf("redis: failed to create pubsub pool: %w", err))
}
// Create the dedicated pipeline pool unconditionally, like pubSubPool: it
// is pure burst capacity (no pre-dialing, small cap, larger buffers — see
// pipelinePoolOptions), so an unused pipeline pool holds zero connections
// and costs nothing. Pipelines stop competing with regular commands for
// main-pool connections; a burst wider than the pool's cap spills back to
// the main pool (see withPipelineConn). PipelinePoolSize < 0 opts out.
if opt.PipelinePoolSize >= 0 {
ref, err := c.buildPipelinePool(opt.Addr + "_" + uniqueID + "_pipeline")
if err != nil {
panic(fmt.Errorf("redis: failed to create pipeline connection pool: %w", err))
}
c.pipelinePool = ref
}
if opt.StreamingCredentialsProvider != nil {
c.streamingCredentialsManager = streaming.NewManager(c.connPool, c.opt.PoolTimeout)
c.connPool.AddPoolHook(c.streamingCredentialsManager.PoolHook())
if pp := c.getPipelinePool(); pp != nil {
pp.AddPoolHook(c.streamingCredentialsManager.PoolHook())
}
}
// CSC wiring (SharedTracking): shared cache + per-connection CLIENT TRACKING +
// background drainer. attachCSC is the strategy dispatch entry.
if opt.Protocol == 3 {
var cache Cache
if explicit := opt.ClientSideCache; explicit != nil {
cache = explicitView on GitHub (pinned to c5cad058c7)
Solutions
- Read the wrapped cause (%w) to find the invalid option
- If pipelines are not needed, set Options.PipelinePoolSize = -1 to opt out of the pool entirely
- Fix the conflicting redis.Options field
Example fix
// before
opt := &redis.Options{Addr: addr, PipelinePoolSize: 16, ReadBufferSize: -32}
// after
opt := &redis.Options{Addr: addr, PipelinePoolSize: 16} // valid buffers/default Defensive patterns
Strategy: validation
Validate before calling
if opt.PipelinePoolSize > 0 && opt.PoolSize <= 0 { return errors.New("PipelinePoolSize requires a valid PoolSize") }
client := redis.NewClient(opt) Try / catch
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("redis client init failed: %v", r)
}
}() Prevention
- Set PipelinePoolSize = -1 if pipelines need no dedicated pool
- Introduce PipelinePoolSize gradually and test init in CI
- Keep pipeline pool smaller than the main pool
When it happens
Trigger: Calling redis.NewClient with Options.PipelinePoolSize >= 0 (opt-in) while other pool options cause buildPipelinePool to fail, at redis.go:2132.
Common situations: Setting PipelinePoolSize explicitly for the first time and combining it with an invalid main-pool/buffer option; validating config only partially.
Related errors
- redis: failed to create connection pool: %w
- redis: failed to create pubsub pool: %w
- failed to create operation duration histogram: %w
- failed to create connection count metric: %w
- failed to create connection create time histogram: %w
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/a48f1738a17b607a.
Report an issue: GitHub.