vitessio/vitess · error
stream %d for %v.%v is not in Stopped after copy state: %v,
Error message
stream %d for %v.%v is not in Stopped after copy state: %v, %v
What it means
When the vindex being externalized has an owner and StopAfterCopy is set, Wrangler requires every stream to be in Stopped state with a message containing 'Stopped after copy'. Anything else means the streams are not in the expected post-copy quiescent state.
Source
Thrown at go/vt/wrangler/materializer.go:892
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)
if err != nil {
return err
}
query := fmt.Sprintf("delete from _vt.vreplication where db_name=%s and workflow=%s", encodeString(targetPrimary.DbName()), encodeString(workflow))
_, err = wr.tmc.VReplicationExec(ctx, targetPrimary.Tablet, query)View on GitHub (pinned to 01a25a7d17)
Solutions
- Wait until the copy phase finishes and the streams auto-stop (message shows 'Stopped after copy'), verified via Workflow Show.
- If streams are still running, let them catch up; do not stop them manually.
- If a stream is in Error, fix the cause and restart the workflow so it can complete copy and stop correctly.
- Re-run ExternalizeVindex once all streams report Stopped with 'Stopped after copy'.
Example fix
// before vtctldclient Workflow --workflow corder_vdx_vdx Stop vtctldclient ExternalizeVindex commerce.corder_vdx // wrong stop reason // after: let workflow stop itself after copy, then vtctldclient ExternalizeVindex commerce.corder_vdx
Defensive patterns
Strategy: validation
Validate before calling
for _, s := range streams {
if s.State != binlogdatapb.VReplicationWorkflowState_Stopped ||
!strings.Contains(s.Message, "Stopped after copy") {
return fmt.Errorf("stream %d not ready: %s / %s", s.Id, s.State, s.Message)
}
} Try / catch
if err := wr.ExternalizeVindex(ctx, name); err != nil {
if strings.Contains(err.Error(), "Stopped after copy") {
// wait for copy phase to complete and auto-stop before retrying
}
} Prevention
- Let owned-vindex workflows stop themselves after copy instead of calling Workflow Stop.
- Check stream messages via Workflow Show before externalizing.
- Externalize owned vindexes only after copy completion is confirmed.
When it happens
Trigger: ExternalizeVindex called for an owned vindex whose streams are still Running/Copying, or were stopped for another reason (manual stop, error) so the message lacks 'Stopped after copy'.
Common situations: Impatiently externalizing before the auto-stop-after-copy completed; streams stopped manually via Workflow Stop instead of letting the copy phase complete; a stream errored and was stopped.
Related errors
- stream %d for %v.%v is not in Running 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/550829c71da03aab.
Report an issue: GitHub.