vitessio/vitess · error
stream %d for %v.%v is not in Running state: %v
Error message
stream %d for %v.%v is not in Running state: %v
What it means
During vindex externalization validation, Wrangler checks each vreplication stream on the target shards. When the vindex has no owner (or StopAfterCopy is false), all streams must be in Running state; any other state (Copying, Error, Stopped) fails validation.
Source
Thrown at go/vt/wrangler/materializer.go:887
id, err := row[0].ToCastInt64()
if err != nil {
return err
}
state := binlogdatapb.VReplicationWorkflowState(binlogdatapb.VReplicationWorkflowState_value[row[1].ToString()])
message := row[2].ToString()
var bls binlogdatapb.BinlogSource
sourceBytes, err := row[3].ToBytes()
if err != nil {
return err
}
if err := prototext.Unmarshal(sourceBytes, &bls); err != nil {
return err
}
if sourceVindex.Owner == "" || !bls.StopAfterCopy {
// If there's no owner or we've requested that the workflow NOT be stopped
// after the copy phase completes, then all streams need to be running.
if state != binlogdatapb.VReplicationWorkflowState_Running {
return fmt.Errorf("stream %d for %v.%v is not in Running state: %v", id, targetShard.Keyspace(), targetShard.ShardName(), state)
}
} else {
// If there is an owner, all streams need to be stopped after copy.
if state != binlogdatapb.VReplicationWorkflowState_Stopped || !strings.Contains(message, "Stopped after copy") {
return fmt.Errorf("stream %d for %v.%v is not in Stopped after copy state: %v, %v", id, targetShard.Keyspace(), targetShard.ShardName(), state, message)
}
}
}
return nil
})
if err != nil {
return err
}
if sourceVindex.Owner != "" {
// If there is an owner, we have to delete the streams.
err := forAllTargets(func(targetShard *topo.ShardInfo) error {
targetPrimary, err := wr.ts.GetTablet(ctx, targetShard.PrimaryAlias)View on GitHub (pinned to 01a25a7d17)
Solutions
- Check stream status with vtctldclient Workflow --workflow <name> Show and wait for all streams to be Running.
- If a stream is in Error, fix the underlying cause (e.g. MySQL error on the target) and restart the workflow.
- Restart stopped streams with the workflow Start command, then retry ExternalizeVindex.
- If the vindex has an owner and should stop after copy, ensure the message contains 'Stopped after copy' — otherwise this branch does not apply.
Example fix
// before: externalize while copying vtctldclient ExternalizeVindex commerce.corder_vdx // after: wait until streams are Running vtctldclient Workflow --workflow corder_vdx_vdx Show # all Running vtctldclient ExternalizeVindex commerce.corder_vdx
Defensive patterns
Strategy: validation
Validate before calling
shs, _ := wr.ts.GetVReplicationWorkflow(ctx, "corder_vdx_vdx")
for _, s := range shs.Streams {
if s.State != binlogdatapb.VReplicationWorkflowState_Running {
return fmt.Errorf("stream %d not running yet: %s", s.Id, s.State)
}
} Try / catch
if err := wr.ExternalizeVindex(ctx, name); err != nil {
if strings.Contains(err.Error(), "is not in Running state") {
// poll workflow status with backoff until all streams Running, then retry
}
} Prevention
- Poll Workflow Show until every stream is Running before externalizing ownerless vindexes.
- Do not manually stop ownerless vindex backfill workflows.
- Investigate and fix Error-state streams before externalizing.
When it happens
Trigger: ExternalizeVindex invoked while the backfill/lookup vreplication streams are still copying, in error, or were manually stopped, for an ownerless vindex.
Common situations: Running ExternalizeVindex before the copy phase completed; a stream failed mid-backfill; someone manually stopped the workflow via Workflow...Stop before externalizing an ownerless vindex.
Related errors
- stream %d for %v.%v is not in Stopped after copy state: %v,
- vindex name should be of the form keyspace.vindex: %s
- vindex %s not found in vschema
- value out of range
- one or two tables must be specified
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/608457a0711cb136.
Report an issue: GitHub.