dgraph-io/dgraph · error

failed to start external snapshot stream for group %d: %w

Error message

failed to start external snapshot stream for group %d: %w

What it means

Returned by streamSnapshotForGroup when the initial dc.StreamExtSnapshot(ctx) bidirectional-stream call fails to open. The error wraps the underlying gRPC error with the group ID for context. Without this stream the snapshot data cannot be sent, so the function aborts before touching BadgerDB.

Source

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

		DropData: false,
	}
	if _, err := dc.UpdateExtSnapshotStreamingState(ctx, req); err != nil {
		glog.Errorf("[import] failed to disable drain mode: %v", err)
		return fmt.Errorf("failed to disable drain mode: %v", err)
	}
	glog.Info("[import] successfully disable drain mode")
	return nil
}

// streamSnapshotForGroup handles the actual data streaming process for a single group.
// It opens the BadgerDB at the specified directory and streams all data to the server.
func streamSnapshotForGroup(ctx context.Context, dc api.DgraphClient, pdir string, groupId uint32) error {
	glog.Infof("Opening stream for group %d from directory %s", groupId, pdir)

	// Initialize stream with the server
	out, err := dc.StreamExtSnapshot(ctx)
	if err != nil {
		return fmt.Errorf("failed to start external snapshot stream for group %d: %w", groupId, err)
	}
	defer func() {
		_ = out.CloseSend()
	}()

	// 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)
		}
	}()

View on GitHub (pinned to 759e242be6)

Solutions

  1. Verify Alpha connectivity (grpcurl or dgraph ping) before running the import.
  2. Check that the server supports StreamExtSnapshot; upgrade client/server to matching versions.
  3. Inspect the wrapped gRPC status code: Unavailable/DeadlineExceeded indicates network or timeout, Unimplemented indicates version mismatch.
  4. Increase the gRPC context timeout for large operations.
  5. Retry the import after transient network failures.

Example fix

// before
out, err := dc.StreamExtSnapshot(ctx)
if err != nil {
	return fmt.Errorf("failed to start external snapshot stream for group %d: %w", groupId, err)
}
// after
out, err := dc.StreamExtSnapshot(ctx)
if err != nil {
	if s, ok := status.FromError(err); ok && s.Code() == codes.Unavailable {
		return fmt.Errorf("alpha unreachable for group %d, check server address/health: %w", groupId, err)
	}
	return fmt.Errorf("failed to start external snapshot stream for group %d: %w", groupId, err)
}
Defensive patterns

Strategy: validation

Validate before calling

conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
	return fmt.Errorf("cannot reach alpha %s: %w", addr, err)
}
if err := conn.Invoke(ctx, "/grpc.health.v1.Health/Check", &health.HealthCheckRequest{}, &health.HealthCheckResponse{}); err != nil {
	return fmt.Errorf("alpha unhealthy: %w", err)
}

Type guard

func isStreamSetupFailure(err error) bool {
	if s, ok := status.FromError(err); ok {
		switch s.Code() {
		case codes.Unavailable, codes.Unimplemented, codes.DeadlineExceeded:
			return true
		}
	}
	return false
}

Try / catch

out, err := dc.StreamExtSnapshot(ctx)
if err != nil {
	if s, ok := status.FromError(err); ok && s.Code() == codes.Unimplemented {
		return fmt.Errorf("server does not support StreamExtSnapshot; upgrade server")
	}
	return err
}

Prevention

When it happens

Trigger: Calling StreamExtSnapshot on a DgraphClient whose connection is down; server does not expose the StreamExtSnapshot RPC (version mismatch); context cancelled/deadline exceeded before the stream is established.

Common situations: Wrong --alpha hostname/port in the import command; Alpha restarted mid-import; TLS/mTLS mismatch preventing the gRPC channel; client and server binary versions out of sync.

Related errors


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