vitessio/vitess · info

vstream ended

Error message

vstream ended

What it means

When the source vstream terminates normally (nil or io.EOF from the stream), fetchAndApply returns this sentinel error to signal the controller that it must retry on a different vttablet. It's a retry-control signal rather than a data failure.

Source

Thrown at go/vt/vttablet/tabletmanager/vreplication/vplayer.go:341

			return nil
		}
		return err
	case err := <-streamErr:
		defer func() {
			// cancel and wait for the other thread to finish.
			cancel()
			<-applyErr
		}()
		// If context is done, don't return an error.
		select {
		case <-ctx.Done():
			return nil
		default:
		}
		// If the stream ends normally we have to return an error indicating
		// that the controller has to retry a different vttablet.
		if err == nil || err == io.EOF {
			return errors.New("vstream ended")
		}
		return err
	}
}

// applyStmtEvent applies an actual DML statement received from the source, directly onto the backend database
func (vp *vplayer) applyStmtEvent(ctx context.Context, event *binlogdatapb.VEvent) error {
	sql := event.Statement
	if sql == "" {
		sql = event.Dml
	}
	if event.Type == binlogdatapb.VEventType_SAVEPOINT || vp.canAcceptStmtEvents {
		start := time.Now()
		_, err := vp.query(ctx, sql)
		vp.vr.stats.QueryTimings.Record(vp.phase, start)
		vp.vr.stats.QueryCount.Add(vp.phase, 1)
		return err
	}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. No direct fix needed — the vreplication engine retries and re-establishes the stream, possibly on a different source tablet
  2. If it loops repeatedly, check source tablet health and vstream logs for why streams keep ending (restarts, binlog issues, throttling)
  3. Verify the workflow's source selection / cell preferences if a specific source keeps terminating
Defensive patterns

Strategy: retry

Try / catch

if err := fetchAndApply(ctx); err != nil {
    if strings.Contains(err.Error(), "vstream ended") {
        // normal EOF path — backoff and retry the stream
        time.Sleep(backoff)
        continue
    }
    return err
}

Prevention

When it happens

Trigger: The source vstream ends cleanly (EOF) or returns nil while fetchAndApply is reading events — e.g. the source tablet's VStream closed, binlog rotated, or the source was shut down gracefully.

Common situations: Source tablet restart or PRS during vreplication; source binlog events ended; vttablet picked a source that then closed the stream; expected during workflow resharding when a source catches up and ends.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/1c20e53c72c35bfd. Report an issue: GitHub.