vitessio/vitess · error

CopyAll was interrupted due to context expiration

Error message

CopyAll was interrupted due to context expiration

What it means

CopyAll detects that its context expired during the copy loop and aborts with this error, because the copy phase is not resilient to context cancellation. The context was likely killed by a PlannedReparentShard (PRS) or the configured copy phase duration elapsing.

Source

Thrown at go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go:316

		return nil
	}, vstreamOptions)

	if copyWorkQueue != nil {
		copyWorkQueue.close()
	}

	// Drain late-arriving task results and aggregate.
	if terr := drainAndAggregateErrors(resultCh, serr, preTerrs); terr != nil {
		log.Warn(fmt.Sprintf("task errors in workflow %s: %v", vc.vr.WorkflowName, terr))
		return terr
	}

	// A context expiration was probably caused by a PlannedReparentShard or an
	// elapsed copy phase duration. CopyAll is not resilient to these events.
	select {
	case <-ctx.Done():
		log.Info(fmt.Sprintf("Copy of %v stopped", state.currentTableName))
		return errors.New("CopyAll was interrupted due to context expiration")
	default:
		if err := vc.runPostCopyActionsAndDeleteCopyState(ctx, stopCtx, state.currentTableName); err != nil {
			return err
		}
		if err := vc.updatePos(ctx, gtid); err != nil {
			return err
		}
		log.Info("Completed copy of all tables")
	}
	return nil
}

// runPostCopyActionsAndDeleteCopyState runs post copy actions and deletes the
// copy state entry for a table, signifying that the copy phase is complete for
// that table.
func (vc *vcopier) runPostCopyActionsAndDeleteCopyState(ctx, stopCtx context.Context, tableName string) error {
	if err := vc.vr.execPostCopyActions(ctx, stopCtx, tableName); err != nil {
		return vterrors.Wrapf(err, "failed to execute post copy actions for table %q", tableName)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Increase the workflow's copy phase duration (e.g. --copy_phase_duration / vreplication_copy_phase_duration flag) so large copies finish
  2. Avoid running PlannedReparentShard while a copy is active; retry the copy after the reparent completes
  3. Check for slow copy performance (source load, network, bandwidth throttling) and optimize; copies automatically resume from copy state on retry

Example fix

// before
vtctldclient MoveTables --workflow wf --target-commerce ks --tables big_table   # copy exceeds default phase duration
// after
vtctldclient MoveTables --workflow wf --target-commerce ks --tables big_table --copy-phase-duration 24h
Defensive patterns

Strategy: retry

Validate before calling

// Estimate copy size vs allowed phase duration before starting
rowEst, _ := srcConn.FetchRow("SELECT SUM(table_rows) FROM information_schema.tables WHERE table_schema IN (?)", args)
if rowEst > 10_000_000 { setCopyPhaseDuration("24h") }

Try / catch

err := workflow.Start(ctx)
if errors.Is(err, errCopyInterrupted) || strings.Contains(err.Error(), "interrupted due to context expiration") {
    // Copy state allows resume; retry with longer phase duration and no concurrent PRS
    ctx = context.Background()
    return workflow.Resume(ctx)
}

Prevention

When it happens

Trigger: ctx.Done() fires while copyAll is mid-table-copy — caused by a PlannedReparentShard demoting/moving the tablet, or the workflow's copy-phase-duration timeout expiring before the bulk copy finished.

Common situations: Large datasets that exceed the copy phase time limit; a reparent happening during a MoveTables/Materialize copy; vreplication workflow cancel/timeout settings too aggressive.

Related errors


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