vitessio/vitess · error
row stream send error: %w
Error message
row stream send error: %w
What it means
The initial VStreamRowsResponse (fields, pk fields, gtid) could not be delivered because the underlying send function failed. safeSend returned an error that was not a context cancellation (those produce 'row stream ended'), so it is wrapped as 'row stream send error'.
Source
Thrown at go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go:405
Name: rs.plan.Table.Fields[pk].Name,
Type: rs.plan.Table.Fields[pk].Type,
Charset: rs.plan.Table.Fields[pk].Charset,
Flags: rs.plan.Table.Fields[pk].Flags,
}
}
charsets := make([]collations.ID, len(rs.plan.Table.Fields))
for i, fld := range rs.plan.Table.Fields {
charsets[i] = collations.ID(fld.Charset)
}
err = safeSend(rs.ctx, &binlogdatapb.VStreamRowsResponse{
Fields: rs.plan.fields(),
Pkfields: pkfields,
Gtid: gtid,
})
if err != nil {
return fmt.Errorf("row stream send error: %w", err)
}
// streamQuery sends heartbeats as long as it operates
heartbeatCtx, stopHeartbeats := context.WithCancel(rs.ctx)
defer stopHeartbeats()
heartbeatInterval := rowStreamertHeartbeatInterval
go func() {
heartbeatTicker := time.NewTicker(heartbeatInterval)
defer heartbeatTicker.Stop()
for {
select {
case <-heartbeatCtx.Done():
return
case <-heartbeatTicker.C:
_ = safeSend(heartbeatCtx, &binlogdatapb.VStreamRowsResponse{Heartbeat: true})
}
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Check tablet logs for the underlying send error cause (broken pipe, connection reset) and inspect network/connectivity between the tablet and the VStream consumer.
- Retry the VStream/workflow; copy-phase resumes from checkpoint.
- If it recurs, verify the receiver (vtgate/vtctld) is healthy and that no proxy/load balancer is killing long-lived gRPC streams (idle timeouts).
Defensive patterns
Strategy: retry
Try / catch
err := rowStream(ctx, ...)
if err != nil && strings.Contains(err.Error(), "row stream send error") {
// underlying send failed (network/receiver gone): backoff and retry the stream
time.Sleep(backoff)
retryStream(ctx)
} Prevention
- Monitor network stability between tablet and consumer
- Avoid killing the receiver mid-copy; stop workflows before teardown
- Configure LBs/proxies to allow long-lived gRPC streams
- Use exponential backoff retries for transient send failures
When it happens
Trigger: streamQuery's first safeSend of fields/pkfields/gtid fails — the send callback passed to Stream errors, typically because the receiving gRPC stream to the caller is broken.
Common situations: Network interruption between vtgate/vtctld and the tablet during copy phase start, receiver gone (workflow cancelled concurrently), gRPC stream reset.
Related errors
- stream send error: %v
- primary key %d refers to non-existent column
- cannot build a row streamer plan for the %s table as a lastp
- row stream ended: %w
- failed to load static auth plugin. Plugin configured but grp
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/10d7f5c9e2f0ea87.
Report an issue: GitHub.