{"id":"45bdea9f3821d2c7","repo":"go-redis/redis","slug":"redis-all-sentinels-specified-in-configuration-ar-45bdea","errorCode":null,"errorMessage":"redis: all sentinels specified in configuration are unreachable: %w","messagePattern":"redis: all sentinels specified in configuration are unreachable: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sentinel.go","lineNumber":1051,"sourceCode":"\t\t\t\tcancel()\n\t\t\t})\n\n\t\t\tif sentinelCli != c.sentinel {\n\t\t\t\t_ = sentinelCli.Close()\n\t\t\t}\n\t\t}(i, sentinelAddr)\n\t}\n\n\twg.Wait()\n\tclose(errCh)\n\tif masterAddr != \"\" {\n\t\treturn masterAddr, nil\n\t}\n\terrs := make([]error, 0, len(errCh))\n\tfor err := range errCh {\n\t\terrs = append(errs, err)\n\t}\n\treturn \"\", fmt.Errorf(\"redis: all sentinels specified in configuration are unreachable: %w\", errors.Join(errs...))\n}\n\nfunc (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected bool) ([]string, error) {\n\tc.mu.RLock()\n\tsentinel := c.sentinel\n\tc.mu.RUnlock()\n\n\tif sentinel != nil {\n\t\taddrs, err := c.getReplicaAddrs(ctx, sentinel)\n\t\tif err != nil {\n\t\t\tif isContextError(ctx.Err()) {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// Continue on other errors\n\t\t\tinternal.Logger.Printf(ctx, \"sentinel: Replicas name=%q failed: %s\",\n\t\t\t\tc.opt.MasterName, err)\n\t\t} else if len(addrs) > 0 {\n\t\t\treturn addrs, nil","sourceCodeStart":1033,"sourceCodeEnd":1069,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/sentinel.go#L1033-L1069","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nclient := redis.NewFailoverClient(&redis.FailoverOptions{\n    MasterName:   \"mymaster\",\n    SentinelAddrs: []string{\":26379\"}, // wrong port / unreachable\n})\n\n// after\nclient := redis.NewFailoverClient(&redis.FailoverOptions{\n    MasterName:   \"mymaster\",\n    SentinelAddrs: []string{\"sentinel-0:26379\", \"sentinel-1:26379\", \"sentinel-2:26379\"},\n})","handlingStrategy":"try-catch","validationCode":"func pingSentinels(addrs []string, timeout time.Duration) error {\n    for _, a := range addrs {\n        conn, err := net.DialTimeout(\"tcp\", a, timeout)\n        if err != nil {\n            continue\n        }\n        conn.Close()\n        return nil\n    }\n    return fmt.Errorf(\"no sentinel reachable from %v\", addrs)\n}","typeGuard":null,"tryCatchPattern":"client := redis.NewFailoverClient(opt)\nif err := client.Ping(ctx).Err(); err != nil {\n    // err may wrap 'all sentinels ... unreachable'; log and retry/backoff\n    if strings.Contains(err.Error(), \"all sentinels\") {\n        // retry with backoff or surface to operator\n    }\n}","preventionTips":["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."],"tags":["sentinel","failover","network","connectivity","configuration"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}