go-redis/redis · error
redis: all sentinels specified in configuration are unreacha
Error message
redis: all sentinels specified in configuration are unreachable: %w
What it means
Returned (not panicked) by sentinelFailover.masterAddr when every configured Sentinel address failed the GetMasterAddrByName query. Each per-sentinel error is collected and joined into the wrapped cause. An empty masterAddr after the fan-out wait means no Sentinel was reachable or knew the master.
Source
Thrown at sentinel.go:1051
cancel()
})
if sentinelCli != c.sentinel {
_ = sentinelCli.Close()
}
}(i, sentinelAddr)
}
wg.Wait()
close(errCh)
if masterAddr != "" {
return masterAddr, nil
}
errs := make([]error, 0, len(errCh))
for err := range errCh {
errs = append(errs, err)
}
return "", fmt.Errorf("redis: all sentinels specified in configuration are unreachable: %w", errors.Join(errs...))
}
func (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected bool) ([]string, error) {
c.mu.RLock()
sentinel := c.sentinel
c.mu.RUnlock()
if sentinel != nil {
addrs, err := c.getReplicaAddrs(ctx, sentinel)
if err != nil {
if isContextError(ctx.Err()) {
return nil, err
}
// Continue on other errors
internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s",
c.opt.MasterName, err)
} else if len(addrs) > 0 {
return addrs, nilView on GitHub (pinned to 36d97525cd)
Solutions
- Verify each Sentinel address in SentinelAddrs is reachable (telnet/curl to port 26379) from the client host.
- Confirm MasterName matches the monitor name configured on the Sentinels (sentinel masters).
- Check the wrapped error(s) for the specific failure (connection refused, timeout, authentication, i/o).
- Add additional/fallback Sentinel addresses and ensure at least one is healthy.
- If using TLS or auth, make sure Sentinel credentials/options match the Sentinel deployment.
Example fix
// before
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{":26379"}, // wrong port / unreachable
})
// after
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{"sentinel-0:26379", "sentinel-1:26379", "sentinel-2:26379"},
}) Defensive patterns
Strategy: try-catch
Validate before calling
func pingSentinels(addrs []string, timeout time.Duration) error {
for _, a := range addrs {
conn, err := net.DialTimeout("tcp", a, timeout)
if err != nil {
continue
}
conn.Close()
return nil
}
return fmt.Errorf("no sentinel reachable from %v", addrs)
} Try / catch
client := redis.NewFailoverClient(opt)
if err := client.Ping(ctx).Err(); err != nil {
// err may wrap 'all sentinels ... unreachable'; log and retry/backoff
if strings.Contains(err.Error(), "all sentinels") {
// retry with backoff or surface to operator
}
} Prevention
- Run a TCP reachability check against every Sentinel address at startup.
- Configure at least three Sentinel addresses for quorum tolerance.
- Verify MasterName against 'sentinel masters' output before deploying.
- Wrap NewFailoverClient usage with a retry/backoff and alerting on this error.
When it happens
Trigger: Using redis.NewFailoverClient / NewFailoverClusterClient where every address in SentinelAddrs is unreachable, returns an error, or does not know MasterName; also when SentinelAddrs is populated but MasterName is wrong/empty.
Common situations: Network partition or firewall blocking the Sentinel port (26379), wrong MasterName, Sentinel list pointing at stale/decommissioned hosts, Sentinel process down, TLS mismatch, or DNS resolving but connection refused.
Related errors
- redis: no sentinels configured
- redis: all sentinels specified in configuration are unreacha
- redis: all ring shards are down
- redis: NewSentinelClient nil options
- redis: NewFailoverClusterClient nil options
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/45bdea9f3821d2c7.json.
Report an issue: GitHub.