dgraph-io/dgraph · error
unable to connect to the leader of group [%v] : %v
Error message
unable to connect to the leader of group [%v] : %v
What it means
InStream is the server side of the StreamExtSnapshot import RPC. Before it can forward snapshot data it resolves the leader of the target group via groups().Leader(groupId); if no leader is reachable (nil) the operation cannot proceed and it returns this error wrapping conn.ErrNoConnection. It means this node knows of the group but has no healthy gRPC connection to its leader.
Source
Thrown at worker/import.go:370
if err != nil {
return fmt.Errorf("failed to receive initial stream message: %v", err)
}
if err := stream.Send(&api.StreamExtSnapshotResponse{Finish: false}); err != nil {
return fmt.Errorf("failed to send initial response: %v", err)
}
groupId := req.GroupId
if groupId == groups().Node.gid {
glog.Infof("[import] streaming external snapshot to current group [%v]", groupId)
return streamInGroup(stream, true)
}
glog.Infof("[import] streaming external snapshot to other group [%v]", groupId)
pl := groups().Leader(groupId)
if pl == nil {
glog.Errorf("[import] unable to connect to the leader of group [%v]", groupId)
return fmt.Errorf("unable to connect to the leader of group [%v] : %v", groupId, conn.ErrNoConnection)
}
con := pl.Get()
c := pb.NewWorkerClient(con)
alphaStream, err := c.StreamExtSnapshot(stream.Context())
if err != nil {
glog.Errorf("[import] failed to establish stream with leader: %v", err)
return fmt.Errorf("failed to establish stream with leader: %v", err)
}
glog.Infof("[import] [forward %d -> %d] start", groups().Node.gid, groupId)
glog.Infof("[import] [forward %v -> %d] start", groups().Node.MyAddr, groups().Leader(groupId).Addr)
glog.Infof("[import] sending forward true to leader of group [%v]", groupId)
forwardReq := &api.StreamExtSnapshotRequest{Forward: true}
if err := alphaStream.Send(forwardReq); err != nil {
glog.Errorf("[import] failed to send forward request: %v", err)
return fmt.Errorf("failed to send forward request: %v", err)
}View on GitHub (pinned to 759e242be6)
Solutions
- Verify the leader of the target group exists and is healthy (dgraph group/health endpoints or logs showing a leader elected for that group)
- Wait for membership/raft to converge after restart, then retry the import
- Check network connectivity and the internal port (default 7080) between the importing node and the target leader
- Confirm groupId matches a group that actually holds data in this cluster
- Retry the whole StreamExtSnapshot import once the cluster is healthy
Example fix
// before
pl := groups().Leader(groupId)
if pl == nil {
return fmt.Errorf("unable to connect to the leader of group [%v] : %v", groupId, conn.ErrNoConnection)
}
// after: add bounded retry to ride out election lag
var pl *conn.Node
for i := 0; i < 10 && pl == nil; i++ {
pl = groups().Leader(groupId)
if pl == nil {
time.Sleep(2 * time.Second)
}
}
if pl == nil {
return fmt.Errorf("unable to connect to the leader of group [%v] : %v", groupId, conn.ErrNoConnection)
} Defensive patterns
Strategy: retry
Validate before calling
// client-side precheck before starting the import
leader, err := dc.CheckDgraphLeader(groupID) // query /health or /state for a leader in the target group
if err != nil || leader == nil {
return fmt.Errorf("no healthy leader for group %v; aborting import", groupID)
} Type guard
func hasLeader(gid uint32) bool {
n := groups().Leader(gid) // server-side guard used before dialing
return n != nil && n.Get() != nil
} Try / catch
err := runImport(ctx)
if err != nil && strings.Contains(err.Error(), "unable to connect to the leader") {
// wait for raft elections, retry with backoff
} Prevention
- Wait for all groups to report a leader before starting an import
- Verify internal port (7080) reachability between all alphas
- Pin imports to a stable, fully-replicated cluster
- Retry imports with backoff after restarts
When it happens
Trigger: groups().Leader(groupId) returns nil because the target group's leader is down, the membership/raft state has not converged yet, or groupId refers to a group that has no tablets/leader in this cluster.
Common situations: Import started immediately after cluster restart before Raft elections complete; leader of target group crashed mid-import; firewall blocks the internal gRPC port so the pool has no healthy connection; typos or stale groupId from an older snapshot manifest.
Related errors
- failed to initiate external snapshot stream: %v
- failed to turn off drain mode: %v
- connection string cannot be empty
- failed to connect to endpoint [%s]: %w
- Unhealthy connection to %v
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/7ea72ca016a78eca.
Report an issue: GitHub.