go-redis/redis · critical
redis: NewRing nil options
Error message
redis: NewRing nil options
What it means
NewRing panics with 'redis: NewRing nil options' when the supplied *RingOptions is nil. Like NewClient, the constructor (ring.go:626-629) documents and enforces this with a panic because a Ring needs at least the Addrs map to build shards; a nil options struct is a programming defect. The panic happens during ring initialization, before any heartbeat or shard is started.
Source
Thrown at ring.go:628
//
// Ring should be used when you need multiple Redis servers for caching
// and can tolerate losing data when one of the servers dies.
// Otherwise you should use Redis Cluster.
type Ring struct {
cmdable
hooksMixin
opt *RingOptions
sharding *ringSharding
cmdsInfoCache *cmdsInfoCache
heartbeatCancelFn context.CancelFunc
}
// NewRing returns a Redis Ring client to the Redis Server specified by RingOptions.
// Passing nil RingOptions will cause a panic.
func NewRing(opt *RingOptions) *Ring {
if opt == nil {
panic("redis: NewRing nil options")
}
// Shallow-copy the options: the ring-wide HIMPORT registry is carried
// through them to shard construction, and reusing one caller-owned
// RingOptions across several rings must not make the rings share (or
// clobber each other's) registry.
optCopy := *opt
opt = &optCopy
opt.init()
// The registry must exist before the first shard is created; shards
// adopt it in newRingShard.
opt.himport = newHImportRegistry()
hbCtx, hbCancel := context.WithCancel(context.Background())
ring := Ring{
opt: opt,
sharding: newRingSharding(opt),
heartbeatCancelFn: hbCancel,View on GitHub (pinned to 36d97525cd)
Solutions
- Always pass a non-nil *RingOptions, at minimum &redis.RingOptions{Addrs: map[string]string{...}}.
- Make your options loader return a valid *RingOptions with sane defaults rather than nil; fail loudly in config validation if Addrs is empty.
- Guard at the call site: if opt == nil { opt = &redis.RingOptions{Addrs: defaultAddrs} } or surface an error from your factory.
- Add a constructor wrapper that validates Addrs is non-empty and returns an error instead of letting go-redis panic.
Example fix
// before
ring := redis.NewRing(loadRingCfg()) // returns nil
// after
opt := loadRingCfg()
if opt == nil {
opt = &redis.RingOptions{Addrs: map[string]string{"shard1": ":6379"}}
}
ring := redis.NewRing(opt) Defensive patterns
Strategy: validation
Validate before calling
func newRing(opt *redis.RingOptions) (*redis.Ring, error) {
if opt == nil {
return nil, errors.New("ring options must not be nil")
}
if len(opt.Addrs) == 0 {
return nil, errors.New("ring options require at least one addr")
}
return redis.NewRing(opt), nil
} Type guard
func validRingOptions(opt *redis.RingOptions) bool {
return opt != nil && len(opt.Addrs) > 0
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Fatalf("redis ring init failed: %v", r)
}
}()
ring := redis.NewRing(opt) Prevention
- Always pass &redis.RingOptions{Addrs: map[string]string{...}}.
- Have your config loader return a valid *RingOptions with defaults instead of nil.
- Wrap NewRing in a factory that validates Addrs and returns an error.
- Validate config (non-empty Addrs) at startup, not on first command.
When it happens
Trigger: Calling redis.NewRing(nil); passing a *RingOptions variable that was declared but never assigned; a config builder that returns nil RingOptions when no addrs were configured; refactoring that extracts ring construction into a helper returning nil on the empty case.
Common situations: Multi-shard config sourced from YAML/env where the ring section is missing so the loader yields nil; conditional client selection (Ring vs Client vs Cluster) where the Ring branch runs with an unpopulated options pointer; tests that omit the options argument.
Related errors
- redis: NewClient nil options
- redis: NewUniversalClient nil options
- redis: all ring shards are down
- redis: the shard is not in the ring
- redis: NewSentinelClient nil options
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/d64974d819b18c51.json.
Report an issue: GitHub.