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
- Ensure the client and all alphas run compatible Dgraph versions
- Find which peer sent the malformed frame via the surrounding [import] logs and fix or upgrade it
- 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
- Never mix Dgraph versions in a cluster
- Always populate Pkt on non-Forward stream messages
- Test custom importers against the real gRPC schema
- Log and drop malformed frames at the client before sending
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
- downstream(%d) closed before Finish=true
- connection string cannot be empty
- while calling MovePredicate
- Tablets are empty in %+v
- Group ID is Zero in %+v
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/e005c89cdf5a9d9b.
Report an issue: GitHub.