dgraph-io/dgraph · critical

failed to send data to majority of the nodes

Error message

failed to send data to majority of the nodes

What it means

When a leader forwards the external snapshot to its group members (forward=true), each member's success is tracked in successfulNodes. After the stream completes, checkMajority applies Raft quorum rules; if fewer than a majority of members received the data, the leader rejects the snapshot with this error to guarantee durability.

Source

Thrown at worker/import.go:639

		}
		return nil
	})

	if err := eg.Wait(); err != nil {
		return fmt.Errorf("failed to run in group streaming: %v", err)
	}
	// Sends a StreamExtSnapshotResponse with the Finish flag set to true to indicate
	// the completion of the streaming process. If an error occurs during the send
	// operation, it is returned for further handling.
	if err := stream.Send(&api.StreamExtSnapshotResponse{Finish: true}); err != nil {
		glog.Errorf("failed to send done signal: %v", err)
	}

	// If this node is the leader and fails to reach a majority of nodes, we return an error.
	// This ensures that the data is reliably received by enough nodes before proceeding.
	if forward && !checkMajority(successfulNodes) {
		glog.Error("[import] Majority of nodes failed to receive data.")
		return fmt.Errorf("failed to send data to majority of the nodes")
	}
	return nil
}

func updateNodeStatus(ps *sync.RWMutex, successfulNodes map[string]bool, addr string, status bool) {
	ps.Lock()
	successfulNodes[addr] = status
	ps.Unlock()
}

// Calculate majority based on Raft quorum rules with special handling for small clusters
func checkMajority(successfulNodes map[string]bool) bool {
	totalNodes := len(successfulNodes)
	successfulCount := 0

	for _, success := range successfulNodes {
		if success {
			successfulCount++

View on GitHub (pinned to 759e242be6)

Solutions

  1. Bring failed replicas back online (check Zero membership state, restart dead alphas) and retry the import.
  2. Verify internal gRPC (port 7080) connectivity between all group members.
  3. Ensure the group has enough healthy members for quorum (e.g. at least 2 of 3) before importing.
  4. Check replication factor / number of replicas in the group; with a single replica quorum always requires it to succeed.
  5. Remove or repair permanently dead replicas so the alive members form a majority.

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// before import: ensure quorum is possible
alive := countAliveMembers(gid)
if alive*2 <= totalMembers(gid) {
    return errors.New("cannot import: group lacks quorum; repair replicas first")
}

Try / catch

err := streamSnapshot(ctx)
if err != nil && strings.Contains(err.Error(), "failed to send data to majority") {
    // restart/repair dead replicas, then retry the import
}

Prevention

When it happens

Trigger: More than half of the group's members failed during forwarding — peers dead (member.AmDead), connection pool errors, failed peer streams, or local subscriber errors — while forward=true.

Common situations: Running a snapshot import while one or more replicas are down or network-partitioned; replicas marked dead in Zero membership; firewall between alphas blocking the internal gRPC port (7080).

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/6022f6841e66b1fa. Report an issue: GitHub.