{"record":{"id":"7452ad061e33ead5","repo":"dgraph-io/dgraph","slug":"unhealthy-connection-to-v","errorCode":null,"errorMessage":"Unhealthy connection to %v","messagePattern":"Unhealthy connection to (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"dgraph/cmd/zero/raft.go","lineNumber":666,"sourceCode":"\t\t\tn.server.SetMembershipState(zs.State)\n\t\t\tfor _, id := range sp.Metadata.ConfState.Voters {\n\t\t\t\tn.Connect(id, zs.State.Zeros[id].Addr)\n\t\t\t}\n\t\t}\n\n\t\tn.SetRaft(raft.RestartNode(n.Cfg))\n\t\tfoundCID, err := n.checkForCIDInEntries()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !foundCID {\n\t\t\tgo n.proposeNewCID()\n\t\t}\n\n\tcase len(opts.peer) > 0:\n\t\tp := conn.GetPools().Connect(opts.peer, opts.tlsClientConfig)\n\t\tif p == nil {\n\t\t\treturn errors.Errorf(\"Unhealthy connection to %v\", opts.peer)\n\t\t}\n\n\t\ttimeout := 8 * time.Second\n\t\tfor {\n\t\t\tc := pb.NewRaftClient(p.Get())\n\t\t\tctx, cancel := context.WithTimeout(n.ctx, timeout)\n\t\t\t// JoinCluster can block indefinitely, raft ignores conf change proposal\n\t\t\t// if it has pending configuration.\n\t\t\t_, err := c.JoinCluster(ctx, n.RaftContext)\n\t\t\tif err == nil {\n\t\t\t\tcancel()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif x.ShouldCrash(err) {\n\t\t\t\tcancel()\n\t\t\t\tlog.Fatalf(\"Error while joining cluster: %v\", err)\n\t\t\t}\n\t\t\tglog.Errorf(\"Error while joining cluster: %v\\n\", err)","sourceCodeStart":648,"sourceCodeEnd":684,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/dgraph/cmd/zero/raft.go#L648-L684","documentation":"When starting a Zero node with an explicit --peer, initAndStartNode obtains a connection pool to that peer via conn.GetPools().Connect. If no healthy connection can be established, it returns this error before attempting to join the raft group — Zero cannot talk to the specified peer at all.","triggerScenarios":"Starting dgraph zero with --peer set to an address where no Zero is listening, the peer is down, TLS client config mismatches the peer, or the network/firewall blocks the gRPC port.","commonSituations":"Typo in --peer host:port; peer Zero not yet started (ordering issue in scripts); wrong port (default 5080); k8s service DNS not resolving; mTLS configured on one side only.","solutions":["Verify the peer Zero is running and reachable at the exact host:port (e.g. nc/curl the gRPC port 5080).","Check --tls_client_config flags match the peer's TLS setup.","Fix DNS/firewall so the peer address resolves and the port is open.","Start the peer Zero before this node, or remove --peer to bootstrap a new group."],"exampleFix":"// before\ndgraph zero --peer \"zero-1.local:5080\"  # zero-1 not up yet -> Unhealthy connection\n// after\n# ensure peer is running first, then:\ndgraph zero --peer \"zero-1.local:5080\" --my \"zero-2.local:5080\"","handlingStrategy":"retry","validationCode":"// Go: verify peer reachability before starting zero\nconn, err := net.DialTimeout(\"tcp\", peerAddr, 5*time.Second)\nif err != nil {\n\treturn fmt.Errorf(\"peer %s unreachable: %w\", peerAddr, err)\n}\nconn.Close()","typeGuard":"func healthyPool(p *pool.Pool) bool { return p != nil }","tryCatchPattern":"err := startZero()\nfor i := 0; err != nil && i < 5; i++ {\n\tif strings.Contains(err.Error(), \"Unhealthy connection\") {\n\t\ttime.Sleep(time.Duration(1<<i) * time.Second) // peer may still be booting\n\t\terr = startZero()\n\t\tcontinue\n\t}\n\tbreak\n}","preventionTips":["Start the peer Zero node before joining nodes","Double-check --peer host:port (default Zero gRPC port is 5080)","Match --tls_client_config on both peers","Use health checks/readiness gates in k8s before launching dependents"],"tags":["network","grpc","zero","raft"],"backgroundTag":"connection-refused","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}