{"record":{"id":"77a4863730967b94","repo":"redis/go-redis","slug":"redis-failed-to-create-connection-pool-w","errorCode":null,"errorMessage":"redis: failed to create connection pool: %w","messagePattern":"redis: failed to create connection pool: %w","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"redis.go","lineNumber":2116,"sourceCode":"\t}\n\tc.init()\n\n\t// Initialize push notification processor using shared helper\n\t// Use void processor for RESP2 connections (push notifications not available)\n\tc.pushProcessor = initializePushProcessor(opt)\n\t// set opt push processor for child clients\n\tc.opt.PushNotificationProcessor = c.pushProcessor\n\n\t// Generate unique pool names for metrics\n\tuniqueID := generateUniqueID()\n\tmainPoolName := opt.Addr + \"_\" + uniqueID\n\tpubsubPoolName := opt.Addr + \"_\" + uniqueID + \"_pubsub\"\n\n\t// Create connection pools\n\tvar err error\n\tc.connPool, err = newConnPool(opt, c.dialHook, mainPoolName)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"redis: failed to create connection pool: %w\", err))\n\t}\n\tc.pubSubPool, err = newPubSubPool(opt, c.dialHook, pubsubPoolName)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"redis: failed to create pubsub pool: %w\", err))\n\t}\n\n\t// Create the dedicated pipeline pool unconditionally, like pubSubPool: it\n\t// is pure burst capacity (no pre-dialing, small cap, larger buffers — see\n\t// pipelinePoolOptions), so an unused pipeline pool holds zero connections\n\t// and costs nothing. Pipelines stop competing with regular commands for\n\t// main-pool connections; a burst wider than the pool's cap spills back to\n\t// the main pool (see withPipelineConn). PipelinePoolSize < 0 opts out.\n\tif opt.PipelinePoolSize >= 0 {\n\t\tref, err := c.buildPipelinePool(opt.Addr + \"_\" + uniqueID + \"_pipeline\")\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"redis: failed to create pipeline connection pool: %w\", err))\n\t\t}\n\t\tc.pipelinePool = ref","sourceCodeStart":2098,"sourceCodeEnd":2134,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/redis.go#L2098-L2134","documentation":"This panic wraps the error returned when go-redis fails to construct the main connection pool for a new Client. Pool construction itself almost never fails at creation time (it does not dial yet); a failure here indicates a programmatically invalid pool configuration. Because NewClient cannot return a partially usable client, the library panics.","triggerScenarios":"Calling redis.NewClient (or any client constructor that calls newConnPool at redis.go:2116) with options that make internal/pool.NewConnPool return an error — most commonly invalid buffer-size or pool-size combinations such as negative PoolSize, or a custom Dialer/option set rejected during pool init.","commonSituations":"Copy-pasted option structs with PoolSize set to a negative value; building Options dynamically from env vars where a missing numeric default becomes a negative; mixing PoolSize/MinIdleConns constraints that the pool constructor rejects.","solutions":["Print the wrapped cause with errors.Unwrap / %w — the inner error names the exact invalid option","Fix the offending redis.Options field (e.g. ensure PoolSize > 0)","Recover from the panic in wrappers that construct clients from user-supplied config and return the error instead"],"exampleFix":"// before\nopt := &redis.Options{Addr: addr, PoolSize: cfg.PoolSize} // cfg.PoolSize = -1\nclient := redis.NewClient(opt) // panics\n// after\npoolSize := cfg.PoolSize\nif poolSize <= 0 {\n    poolSize = 10 * runtime.GOMAXPROCS(0)\n}\nopt := &redis.Options{Addr: addr, PoolSize: poolSize}\nclient := redis.NewClient(opt)","handlingStrategy":"validation","validationCode":"if opt.PoolSize <= 0 { return fmt.Errorf(\"PoolSize must be positive, got %d\", opt.PoolSize) }\n_ = redis.NewClient(opt)","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = fmt.Errorf(\"redis client init failed: %v\", r)\n    }\n}()","preventionTips":["Validate all redis.Options numeric fields are non-negative before NewClient","Prefer library defaults over hand-set pool sizes","Centralize client construction in one factory with config validation"],"tags":["go","client-init","panic","connection-pool"],"backgroundTag":"invalid-pool-configuration","analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}