{"id":"b44a8cbb3ccc4e45","repo":"go-redis/redis","slug":"redis-stickyconnpool-get-infinite-loop","errorCode":null,"errorMessage":"redis: StickyConnPool.Get: infinite loop","messagePattern":"redis: StickyConnPool\\.Get: infinite loop","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pool/pool_sticky.go","lineNumber":104,"sourceCode":"\t\t\t\treturn cn, nil\n\t\t\t}\n\t\t\tp.pool.Remove(ctx, cn, ErrClosed)\n\t\tcase stateInited:\n\t\t\tif err := p.badConnError(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcn, ok := <-p.ch\n\t\t\tif !ok {\n\t\t\t\treturn nil, ErrClosed\n\t\t\t}\n\t\t\treturn cn, nil\n\t\tcase stateClosed:\n\t\t\treturn nil, ErrClosed\n\t\tdefault:\n\t\t\tpanic(\"not reached\")\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"redis: StickyConnPool.Get: infinite loop\")\n}\n\n// SetOnFirstConn configures a callback that runs when the sticky pool first\n// claims a parent connection. It must be called before the pool is used.\nfunc (p *StickyConnPool) SetOnFirstConn(fn func(*Conn)) {\n\tp.onFirstConn = fn\n}\n\nfunc (p *StickyConnPool) Put(ctx context.Context, cn *Conn) {\n\tdefer func() {\n\t\tif recover() != nil {\n\t\t\tp.freeConn(ctx, cn)\n\t\t}\n\t}()\n\t// A connection marked for removal on release (it may hold unread\n\t// replies) must not be served to the next Get: record it as a bad\n\t// connection — exactly like Remove — so Get refuses and the underlying\n\t// connection is removed from the parent pool when the sticky pool","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/internal/pool/pool_sticky.go#L86-L122","documentation":"Error \"redis: StickyConnPool.Get: infinite loop\" thrown in go-redis/redis.","triggerScenarios":"Thrown at internal/pool/pool_sticky.go:104 when the library encounters an invalid state.","commonSituations":"Guard sticky pool access with clear ownership (one goroutine or serialized use).","solutions":["Report/upgrade: this indicates a pool bug; as a workaround recreate the StickyConnPool","Avoid concurrent Get/Close on the sticky pool"],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}