vitessio/vitess · error

migration cannot run because prior migration in same…

Error message

migration %v cannot run because prior migration %v in same context has failed/was cancelled

What it means

During schema analysis of a new online DDL migration, vttablet checks whether any prior migration submitted in the same context/keyspace has failed or been cancelled. If so, the new migration is immediately failed with this message to avoid building on an inconsistent schema change sequence.

Solutions

  1. Find and fix the root cause of the earlier failed/cancelled migration (check its message via SHOW VITESS_MIGRATIONS)
  2. Retry or revert the failed migration so its status no longer blocks the context
  3. Submit the new migration in a different migration context if it is genuinely independent
  4. Cancel/clean up stale migrations in the queue before resubmitting
Defensive patterns

Strategy: validation

Validate before calling

// Before submitting a new migration, ensure no failed/cancelled migrations share the context
rows := query(t, "SELECT uuid FROM _vt.schema_migrations WHERE migration_context=? AND status IN ('failed','cancelled')", ctxName)
if len(rows) > 0 {
    return fmt.Errorf("context %s blocked by failed migration %s", ctxName, rows[0].uuid)
}

Try / catch

err := applySchema(ctx, ddl, migrationContext)
if err != nil && strings.Contains(err.Error(), "has failed/was cancelled") {
    // resolve the earlier failed migration, then resubmit
}

Prevention

When it happens

Trigger: Submitting an ALTER/DROP migration in the same migration context where an earlier migration (uuids[0]) ended in status 'failed' or 'cancelled'.

Common situations: A batch of sequential schema changes where migration #1 failed (e.g. table locked, timeout) and subsequent migrations in the same submit request are rejected; CI pipelines replaying migration sequences after a failure.

Related errors


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

Appendix: source

Thrown at go/vt/vttablet/onlineddl/executor.go:2451

	e.ownedRunningMigrations.Delete(onlineDDL.UUID)
	return withError
}

// validateInOrderMigration checks whether an in-order migration should be forced to fail, either before running or
// while running.
// This may happen if a prior migration in the same context has failed or was cancelled.
func (e *Executor) validateInOrderMigration(ctx context.Context, onlineDDL *schema.OnlineDDL) (wasFailed bool, err error) {
	if !onlineDDL.StrategySetting().IsInOrderCompletion() {
		return false, nil
	}
	uuids, err := e.readFailedCancelledMigrationsInContextBeforeMigration(ctx, onlineDDL)
	if err != nil {
		return false, err
	}
	if len(uuids) == 0 {
		return false, err
	}
	return true, e.failMigration(ctx, onlineDDL, fmt.Errorf("migration %v cannot run because prior migration %v in same context has failed/was cancelled", onlineDDL.UUID, uuids[0]))
}

// analyzeDropDDLActionMigration analyzes a DROP <TABLE|VIEW> migration.
func (e *Executor) analyzeDropDDLActionMigration(ctx context.Context, onlineDDL *schema.OnlineDDL) error {
	// Schema analysis:
	originalShowCreateTable, err := e.showCreateTable(ctx, onlineDDL.Table)
	if err != nil {
		if sqlErr, isSQLErr := sqlerror.NewSQLErrorFromError(err).(*sqlerror.SQLError); isSQLErr {
			switch sqlErr.Num {
			case sqlerror.ERNoSuchTable:
				// The table does not exist. For analysis purposed, that's fine.
				return nil
			default:
				return vterrors.Wrapf(err, "attempting to read definition of %v", onlineDDL.Table)
			}
		}
	}
	stmt, err := e.env.Environment().Parser().ParseStrictDDL(originalShowCreateTable)

View on GitHub (pinned to 01a25a7d17)