dgraph-io/dgraph · error

failed to send request for group ID [%v] to the server: %w

Error message

failed to send request for group ID [%v] to the server: %w

What it means

Returned when out.Send of the first StreamExtSnapshotRequest (carrying only the GroupId) fails on the open stream. The server expects the group ID as the first message; a send failure means the stream is broken before any data flows.

Source

Thrown at dgraph/cmd/dgraphimport/import_client.go:196

	// Open the BadgerDB instance at the specified directory
	opt := badger.DefaultOptions(pdir)
	opt.ReadOnly = true
	ps, err := badger.OpenManaged(opt)
	if err != nil {
		glog.Errorf("failed to open BadgerDB at [%s]: %v", pdir, err)
		return fmt.Errorf("failed to open BadgerDB at [%v]: %v", pdir, err)
	}
	defer func() {
		if err := ps.Close(); err != nil {
			glog.Warningf("[import] Error closing BadgerDB: %v", err)
		}
	}()

	// Send group ID as the first message in the stream
	glog.Infof("[import] Sending request for streaming external snapshot for group ID [%v]", groupId)
	groupReq := &api.StreamExtSnapshotRequest{GroupId: groupId}
	if err := out.Send(groupReq); err != nil {
		return fmt.Errorf("failed to send request for group ID [%v] to the server: %w", groupId, err)
	}
	if _, err := out.Recv(); err != nil {
		return fmt.Errorf("failed to receive response for group ID [%v] from the server: %w", groupId, err)
	}

	glog.Infof("[import] Group [%v]: Received ACK for sending group request", groupId)

	// Configure and start the BadgerDB stream
	glog.Infof("[import] Starting BadgerDB stream for group [%v]", groupId)
	if err := streamBadger(ctx, ps, out, groupId); err != nil {
		return fmt.Errorf("badger streaming failed for group [%v]: %v", groupId, err)
	}
	return nil
}

// streamBadger runs a BadgerDB stream to send key-value pairs to the specified group.
// It creates a new stream at the maximum sequence number and sends the data to the specified group.
// It also sends a final 'done' signal to mark completion.

View on GitHub (pinned to 759e242be6)

Solutions

  1. Check the wrapped gRPC error/status for the root cause (Unavailable, Canceled, Internal).
  2. Confirm the group ID exists in the current cluster (dgraph status / raft state).
  3. Disable LB idle-timeout killing of long gRPC streams or add keepalive settings.
  4. Retry the whole streamSnapshotForGroup; streams are not resumable.
  5. Verify the Alpha is healthy and not restarting during the import.

Example fix

// before
if err := out.Send(groupReq); err != nil {
	return fmt.Errorf("failed to send request for group ID [%v] to the server: %w", groupId, err)
}
// after
if err := out.Send(groupReq); err != nil {
	if errors.Is(err, io.EOF) {
		return fmt.Errorf("server closed stream for group %d before handshake; check server logs and group membership", groupId)
	}
	return fmt.Errorf("failed to send request for group ID [%v] to the server: %w", groupId, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ctx.Err() != nil {
	return fmt.Errorf("context already cancelled before stream handshake: %w", ctx.Err())
}

Type guard

func isEOFOrBrokenStream(err error) bool {
	return errors.Is(err, io.EOF) ||
		(errors.Is(err, context.Canceled)) ||
		(func() bool { s, ok := status.FromError(err); return ok && s.Code() == codes.Unavailable }())
}

Try / catch

if err := out.Send(groupReq); err != nil {
	if isEOFOrBrokenStream(err) {
		// stream died before handshake: rebuild stream and retry once
		return retryStreamSnapshotForGroup(ctx, dc, pdir, groupId)
	}
	return fmt.Errorf("failed to send request for group ID [%v] to the server: %w", groupId, err)
}

Prevention

When it happens

Trigger: The gRPC stream was closed by the server right after setup (server-side error, load balancer idle timeout, Alpha crash); context cancelled mid-send; sending on a stream the server already rejected (e.g. unknown group).

Common situations: Long-lived stream killed by an intermediate proxy/LB idle timeout; Alpha draining or restarting between stream open and first send; cluster reconfiguration changed group membership so the group ID is rejected.

Related errors


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