vitessio/vitess · error
VReplication streams must have named workflows for migration
Error message
VReplication streams must have named workflows for migration: shard: %s:%s
What it means
Thrown by readTabletStreams (the non-legacy, ReadVReplicationWorkflows-based path) when a workflow returned from the tablet has an empty name. The stream migrator only supports migrating named VReplication workflows; unnamed streams cannot be tracked, stopped, or recreated on the target shards, so the operation aborts.
Source
Thrown at go/vt/vtctl/workflow/stream_migrator.go:393
func (sm *StreamMigrator) readTabletStreams(ctx context.Context, ti *topo.TabletInfo, ids []int32, states []binlogdatapb.VReplicationWorkflowState, excludeFrozen bool) ([]*VReplicationStream, error) {
req := &tabletmanagerdatapb.ReadVReplicationWorkflowsRequest{
ExcludeWorkflows: []string{sm.ts.ReverseWorkflowName()},
IncludeIds: ids,
IncludeStates: states,
ExcludeFrozen: excludeFrozen,
}
res, err := sm.ts.TabletManagerClient().ReadVReplicationWorkflows(ctx, ti.Tablet, req)
if err != nil {
return nil, err
}
tabletStreams := make([]*VReplicationStream, 0, len(res.Workflows))
for _, workflow := range res.Workflows {
switch workflow.Workflow {
case "":
return nil, fmt.Errorf("VReplication streams must have named workflows for migration: shard: %s:%s",
ti.Keyspace, ti.Shard)
case sm.ts.WorkflowName():
return nil, fmt.Errorf("VReplication stream has the same workflow name as the resharding workflow: shard: %s:%s",
ti.Keyspace, ti.Shard)
}
for _, stream := range workflow.Streams {
isReference, err := sm.blsIsReference(stream.Bls)
if err != nil {
return nil, vterrors.Wrap(err, "blsIsReference")
}
if isReference {
sm.ts.Logger().Infof("readTabletStreams: ignoring reference table %+v", stream.Bls)
continue
}
pos, err := replication.DecodePosition(stream.Pos)View on GitHub (pinned to 01a25a7d17)
Solutions
- Identify the unnamed stream: `select id, workflow from _vt.vreplication` on the source shard primary and find rows with empty workflow.
- Name the stream explicitly (`update _vt.vreplication set workflow='<descriptive-name>' where id=<id>`) and rerun the migration.
- If the stream is obsolete, remove it via vtctldclient Workflow Remove or a DELETE on _vt.vreplication.
- Upgrade tablets to a Vitess version that always populates workflow names, then retry.
Example fix
// before mysql> update _vt.vreplication set id=7 where ...; -- row has workflow='' // after mysql> update _vt.vreplication set workflow='legacy_kd_copy' where id=7;
Defensive patterns
Strategy: validation
Validate before calling
rows, _ := qr.Rows // select id, workflow from _vt.vreplication
for _, r := range rows {
if r["workflow"].ToString() == "" {
return fmt.Errorf("stream %d has no workflow name; name or delete it before migrating", id)
}
} Type guard
func hasWorkflowName(workflow string) bool {
return strings.TrimSpace(workflow) != ""
} Try / catch
if err := migrateStreams(ctx, cfg); err != nil && strings.Contains(err.Error(), "must have named workflows") {
// locate unnamed stream in _vt.vreplication, name or remove it, retry
} Prevention
- Upgrade to a Vitess version that always records workflow names
- Audit for empty workflow columns before migrations
- Avoid direct INSERTs into _vt.vreplication
When it happens
Trigger: Calling stream migration (MigrateStreams / MoveTables stream transfer) against a source shard primary whose _vt.vreplication rows (as surfaced by ReadVReplicationWorkflows) contain a workflow with an empty Workflow string.
Common situations: Streams created by very old Vitess versions or manual INSERTs into _vt.vreplication without a workflow value; legacy one-off streams predating mandatory workflow names; mixed-version clusters where the tabletmanager returns unnamed rows.
Related errors
- VReplication stream has the same workflow name as the reshar
- VReplication stream has the same workflow name as the reshar
- cannot migrate until all streams are running: %s: %d
- cannot migrate while vreplication streams in source shards a
- streams are mismatched across source shards: %s vs %s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/726f9f4373903b2b.
Report an issue: GitHub.