vitessio/vitess · error
cannot switch traffic for workflow %s at this time: %s
Error message
cannot switch traffic for workflow %s at this time: %s
What it means
SwitchTraffic first runs canSwitch(keyspace, workflowName), which returns a human-readable reason string when conditions for switching read/write traffic are not yet met (e.g. vreplication streams not caught up, wrong workflow state). A non-empty reason aborts the switch with this wrapped error.
Source
Thrown at go/vt/wrangler/workflow.go:344
if vrw.workflowType == MigrateWorkflow {
return nil, errors.New("invalid action for Migrate workflow: SwitchTraffic")
}
vrw.params.Direction = direction
workflowName := vrw.params.Workflow
keyspace := vrw.params.TargetKeyspace
if vrw.params.Direction == workflow.DirectionBackward {
workflowName = workflow.ReverseWorkflowName(workflowName)
keyspace = vrw.params.SourceKeyspace
}
reason, err := vrw.canSwitch(keyspace, workflowName)
if err != nil {
return nil, err
}
if reason != "" {
return nil, fmt.Errorf("cannot switch traffic for workflow %s at this time: %s", workflowName, reason)
}
hasReplica, hasRdonly, hasPrimary, err = vrw.parseTabletTypes()
if err != nil {
return nil, err
}
if hasReplica || hasRdonly {
if rdDryRunResults, err = vrw.switchReads(); err != nil {
return nil, err
}
}
if rdDryRunResults != nil {
dryRunResults = append(dryRunResults, *rdDryRunResults...)
}
if hasPrimary {
if wrDryRunResults, err = vrw.switchWrites(); err != nil {
return nil, err
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Read the reason embedded in the error and address it (most often: wait for target catch-up, check VReplicationWorkflow streams)
- Verify workflow state with the appropriate status commands; resume/restart stuck streams
- Retry the switch once the reason condition clears
Defensive patterns
Strategy: retry
Validate before calling
reason, err := canSwitch(keyspace, workflowName)
if err != nil || reason != "" {
// not ready: wait / fix prerequisite, then retry
} Try / catch
err := retry.Do(func() error {
_, err := wf.SwitchTraffic(ctx, ...)
if err != nil && strings.Contains(err.Error(), "cannot switch traffic") {
return retry.TransientError(err) // retry after catch-up
}
return err
}, retry.Attempts(timeout/retryInterval)) Prevention
- Wait for target replication catch-up before switching traffic
- Check workflow state/status before attempting switch or reverse traffic
- Never run ReverseTraffic immediately after ForwardTraffic without confirming state
When it happens
Trigger: Calling SwitchTraffic (or ReverseTraffic, or testSwitchForward) when canSwitch returns a non-empty reason — commonly replication lag on the target, streams not running, or the workflow not in the expected state.
Common situations: Running PlannedSwitchOver before the target has fully caught up; reverse traffic attempted too soon after a forward switch; a stuck/failed vreplication stream leaving the workflow in a non-switchable state.
Related errors
- value out of range
- both atomic copy and partial mode cannot be specified for th
- invalid workflow
- multiple source keyspaces for a single workflow
- multiple target keyspaces for a single workflow
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/bd233bb87a272a87.
Report an issue: GitHub.