{"id":"8cbc15c2d910cdf2","repo":"go-redis/redis","slug":"failed-to-initialize-connection-options-w","errorCode":null,"errorMessage":"failed to initialize connection options: %w","messagePattern":"failed to initialize connection options: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"redis.go","lineNumber":888,"sourceCode":"\t\t// A server-side rejection means tracking is unavailable, but the\n\t\t// connection and the preceding init commands are still usable. Disable\n\t\t// CSC globally and continue without caching. Transport and protocol\n\t\t// failures still take the normal connection-failure path below.\n\t\tc.disableCSCServing(ctx, fmt.Sprintf(\"CLIENT TRACKING ON was rejected: %v\", trackingCmd.Err()))\n\t\tc.cscForgetConn(cn.GetID())\n\t\ttrackingEnabled = false\n\t\tinitErr = nil\n\t}\n\tif initErr != nil {\n\t\tif trackingEnabled {\n\t\t\t// cscEvictOwnedEntries above bumped this conn's init generation; a\n\t\t\t// failed init never serves, and the pubsub path has no OnRemove\n\t\t\t// hook (and the close hook below is not yet installed), so drop\n\t\t\t// the entry here to keep the map bounded to live conns.\n\t\t\tc.cscForgetConn(cn.GetID())\n\t\t}\n\t\tcn.GetStateMachine().Transition(pool.StateClosed)\n\t\treturn fmt.Errorf(\"failed to initialize connection options: %w\", initErr)\n\t}\n\n\tif trackingEnabled {\n\t\t// Evict this conn's entries on any close (incl. the ConnMaxLifetime/idle\n\t\t// path that bypasses the OnRemove hook), since the server drops its\n\t\t// tracking table on close.\n\t\tc.cscInstallConnCloseHook(cn)\n\t\t// A handoff replaces the socket before initConn runs. Bump and evict at\n\t\t// the pre-swap boundary so fulfillCached cannot publish an old-socket\n\t\t// reply during that gap.\n\t\tc.cscInstallConnReinitHook(cn)\n\t}\n\n\t// Enable maintnotifications if maintnotifications are configured\n\tc.optLock.RLock()\n\tmaintNotifEnabled := c.opt.MaintNotificationsConfig != nil && c.opt.MaintNotificationsConfig.Mode != maintnotifications.ModeDisabled\n\tprotocol := c.opt.Protocol\n\tvar endpointType maintnotifications.EndpointType","sourceCodeStart":870,"sourceCodeEnd":906,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/redis.go#L870-L906","documentation":"Thrown when the pipelined init command batch (SELECT, READONLY, CLIENT SETNAME, CLIENT TRACKING ON) fails with a transport/protocol error rather than a benign server-side rejection. The connection is transitioned to StateClosed and the underlying error is wrapped.","triggerScenarios":"initConn runs the init pipeline and one of the commands fails with a non-redis (network/protocol) error. A server-side rejection of CLIENT TRACKING ON is handled separately (disables CSC); this error is for SELECT failing on a non-zero DB that doesn't exist, READONLY rejected, CLIENT SETNAME rejected, or a connection drop mid-pipeline.","commonSituations":"Options.DB set to a database number that does not exist or is denied by the server (SELECT fails); READONLY issued against a standalone server that rejects it; connection reset by peer or idle timeout between HELLO and the init pipeline; TLS handshake completed but server closed the connection; proxy that only allows a subset of commands.","solutions":["If Options.DB > 0, confirm the server has that database (cluster mode only allows DB 0 — set DB to 0 or remove it).","Disable Options.readOnly if targeting a standalone (non-replica) server that rejects READONLY.","Check for an unstable network/proxy closing the connection right after handshake; look at the wrapped error for i/o or EOF.","Increase connection health and reduce idle eviction; ensure the endpoint is a real Redis-compatible server."],"exampleFix":"// before\nopt := &redis.Options{Addr: clusterAddr, DB: 1}\n// cluster rejects SELECT -> init pipeline fails\n\n// after\nopt := &redis.Options{Addr: clusterAddr, DB: 0}","handlingStrategy":"validation","validationCode":"// Validate DB index and readOnly against the deployment shape.\nif opt.DB != 0 && isCluster {\n    return errors.New(\"DB must be 0 for Redis Cluster\")\n}\nif opt.readOnly && !isReplica {\n    // standalone primary may reject READONLY\n}","typeGuard":null,"tryCatchPattern":"if err := client.Ping(ctx).Err(); err != nil {\n    if strings.Contains(err.Error(), \"failed to initialize connection options\") {\n        // likely a SELECT/READONLY rejection; inspect wrapped error\n    }\n}","preventionTips":["Do not set DB > 0 against Redis Cluster (only DB 0 is valid).","Enable readOnly only when connecting to replicas.","Run an integration test that brings up the client against the real topology before shipping."],"tags":["connection","init","config","network"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}