go-redis/redis · error

failed to initialize connection options: %w

Error message

failed to initialize connection options: %w

What it means

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.

Source

Thrown at redis.go:888

		// A server-side rejection means tracking is unavailable, but the
		// connection and the preceding init commands are still usable. Disable
		// CSC globally and continue without caching. Transport and protocol
		// failures still take the normal connection-failure path below.
		c.disableCSCServing(ctx, fmt.Sprintf("CLIENT TRACKING ON was rejected: %v", trackingCmd.Err()))
		c.cscForgetConn(cn.GetID())
		trackingEnabled = false
		initErr = nil
	}
	if initErr != nil {
		if trackingEnabled {
			// cscEvictOwnedEntries above bumped this conn's init generation; a
			// failed init never serves, and the pubsub path has no OnRemove
			// hook (and the close hook below is not yet installed), so drop
			// the entry here to keep the map bounded to live conns.
			c.cscForgetConn(cn.GetID())
		}
		cn.GetStateMachine().Transition(pool.StateClosed)
		return fmt.Errorf("failed to initialize connection options: %w", initErr)
	}

	if trackingEnabled {
		// Evict this conn's entries on any close (incl. the ConnMaxLifetime/idle
		// path that bypasses the OnRemove hook), since the server drops its
		// tracking table on close.
		c.cscInstallConnCloseHook(cn)
		// A handoff replaces the socket before initConn runs. Bump and evict at
		// the pre-swap boundary so fulfillCached cannot publish an old-socket
		// reply during that gap.
		c.cscInstallConnReinitHook(cn)
	}

	// Enable maintnotifications if maintnotifications are configured
	c.optLock.RLock()
	maintNotifEnabled := c.opt.MaintNotificationsConfig != nil && c.opt.MaintNotificationsConfig.Mode != maintnotifications.ModeDisabled
	protocol := c.opt.Protocol
	var endpointType maintnotifications.EndpointType

View on GitHub (pinned to 36d97525cd)

Solutions

  1. If Options.DB > 0, confirm the server has that database (cluster mode only allows DB 0 — set DB to 0 or remove it).
  2. Disable Options.readOnly if targeting a standalone (non-replica) server that rejects READONLY.
  3. Check for an unstable network/proxy closing the connection right after handshake; look at the wrapped error for i/o or EOF.
  4. Increase connection health and reduce idle eviction; ensure the endpoint is a real Redis-compatible server.

Example fix

// before
opt := &redis.Options{Addr: clusterAddr, DB: 1}
// cluster rejects SELECT -> init pipeline fails

// after
opt := &redis.Options{Addr: clusterAddr, DB: 0}
Defensive patterns

Strategy: validation

Validate before calling

// Validate DB index and readOnly against the deployment shape.
if opt.DB != 0 && isCluster {
    return errors.New("DB must be 0 for Redis Cluster")
}
if opt.readOnly && !isReplica {
    // standalone primary may reject READONLY
}

Try / catch

if err := client.Ping(ctx).Err(); err != nil {
    if strings.Contains(err.Error(), "failed to initialize connection options") {
        // likely a SELECT/READONLY rejection; inspect wrapped error
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /data/errors/8cbc15c2d910cdf2.json. Report an issue: GitHub.