go-redis/redis · critical
redis: NewSentinelClient nil options
Error message
redis: NewSentinelClient nil options
What it means
NewSentinelClient panics when called with a nil *Options pointer. The constructor dereferences opt (opt.init()) immediately after this check, so the guard exists to fail loudly rather than produce a nil-pointer dereference deeper in setup. This is a programmer error, not a runtime/network condition.
Source
Thrown at sentinel.go:691
if failover.opt.TLSConfig == nil {
return netDialer.DialContext(ctx, network, addr)
}
return tls.DialWithDialer(netDialer, network, addr, failover.opt.TLSConfig)
}
}
//------------------------------------------------------------------------------
// SentinelClient is a client for a Redis Sentinel.
type SentinelClient struct {
*baseClient
}
// NewSentinelClient returns a Redis Sentinel client.
// Passing nil Options will cause a panic.
func NewSentinelClient(opt *Options) *SentinelClient {
if opt == nil {
panic("redis: NewSentinelClient nil options")
}
opt.init()
c := &SentinelClient{
baseClient: &baseClient{
apClosed: &atomic.Bool{},
opt: opt,
onClose: &onCloseHooks{},
},
}
// Initialize push notification processor using shared helper
// Use void processor for Sentinel clients
c.pushProcessor = NewVoidPushNotificationProcessor()
c.initHooks(hooks{
dial: c.baseClient.dial,
process: c.baseClient.process,
})View on GitHub (pinned to 36d97525cd)
Solutions
- Ensure the *redis.Options argument is non-nil before calling NewSentinelClient; construct it with &redis.Options{Addr: ...}.
- If options come from a loader, abort early on the loader error instead of propagating a nil pointer.
- Add a nil check at the call site and return a descriptive error to the caller.
Example fix
// before
var opt *redis.Options
c := redis.NewSentinelClient(opt)
// after
c := redis.NewSentinelClient(&redis.Options{Addr: ":26379"}) Defensive patterns
Strategy: validation
Validate before calling
func buildSentinelClient(opt *redis.Options) (*redis.SentinelClient, error) {
if opt == nil {
return nil, errors.New("redis.Options must not be nil")
}
return redis.NewSentinelClient(opt), nil
} Type guard
func isNonNilOptions(opt *redis.Options) bool { return opt != nil } Prevention
- Treat *redis.Options as required: always construct it with &redis.Options{...} inline.
- Never let a config-loader return *redis.Options directly without a non-nil guarantee; return (Options, error) instead.
- Unit-test constructor call paths with a non-nil options fixture.
When it happens
Trigger: Calling redis.NewSentinelClient(nil) directly, or passing an uninitialised *redis.Options variable that was never assigned (e.g. var opt *redis.Options; NewSentinelClient(opt)).
Common situations: Conditional configuration where the options struct is built in a branch that did not execute, a helper that returns *redis.Options returning nil on a config-load failure, or refactoring that accidentally drops the options argument.
Related errors
- redis: NewFailoverClusterClient nil options
- redis: NewClusterClient nil options
- redis: no sentinels configured
- redis: all sentinels specified in configuration are unreacha
- redis: NewClient nil options
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/0469be227cdc306b.json.
Report an issue: GitHub.