dgraph-io/dgraph · error

unexpected empty request

Error message

unexpected empty request

What it means

While relaying, pipeTwoStream expects every upstream message to carry a Pkt payload. If req.Pkt is nil the protocol contract is broken — the peer sent a control-less or malformed frame — and piping is aborted with this error rather than forwarding a nil packet downstream.

Source

Thrown at worker/import.go:410

func pipeTwoStream(in api.Dgraph_StreamExtSnapshotServer, out pb.Worker_StreamExtSnapshotClient, groupId uint32) error {
	currentGroup := groups().Node.gid
	ctx := in.Context()

	for {
		if err := ctx.Err(); err != nil {
			return err
		}

		req, err := in.Recv()
		if errors.Is(err, io.EOF) {
			return nil
		}
		if err != nil {
			return fmt.Errorf("recv upstream(%d): %w", currentGroup, err)
		}
		if req.Pkt == nil {
			return fmt.Errorf("unexpected empty request")
		}

		if req.Pkt.Done {
			// Forward Done, half-close downstream send.
			if err := out.Send(&api.StreamExtSnapshotRequest{Pkt: req.Pkt}); err != nil && !errors.Is(err, io.EOF) {
				return fmt.Errorf("send done downstream(%d): %w", groupId, err)
			}
			_ = out.CloseSend()

			// Drain downstream and relay upstream until Finish=true.
			for {
				if err := ctx.Err(); err != nil {
					return err
				}
				resp, err := out.Recv()
				if errors.Is(err, io.EOF) {
					return fmt.Errorf("downstream(%d) closed before Finish=true", groupId)
				}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Ensure the client and all alphas run compatible Dgraph versions
  2. Find which peer sent the malformed frame via the surrounding [import] logs and fix or upgrade it
  3. If using a custom importer, always populate Pkt (with Done and/or data KVs) on every non-Forward message
Defensive patterns

Strategy: validation

Validate before calling

// custom clients must validate every outgoing message before Send
func validMsg(m *api.StreamExtSnapshotRequest) bool {
    return m.Forward || m.Pkt != nil
}

Type guard

func hasPkt(req *api.StreamExtSnapshotRequest) bool {
    return req != nil && req.Pkt != nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unexpected empty request") {
    // protocol violation by a peer; identify peer version and upgrade
}

Prevention

When it happens

Trigger: A peer sends api.StreamExtSnapshotRequest with neither Forward nor Pkt set (e.g. wrong client version, hand-rolled test client, or corrupted message after a deserialization edge case).

Common situations: Mixed Dgraph versions where the wire schema differs; a custom tool or script speaking the streaming protocol incorrectly; a proxy that truncates/reorders frames.

Related errors


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