vitessio/vitess · error

online DDL is disabled

Error message

online DDL is disabled

What it means

ErrOnlineDDLDisabled is a sentinel error returned when an online-DDL operation is requested (submit/review/control via TryExecute, buildAlterMigrationPlan, buildRevertMigrationPlan, buildShowMigrationLogsPlan) while online DDL is disabled in the configuration. It prevents scheduling gh-ost/pt-osc migrations when the deployment doesn't support or allow them.

Source

Thrown at go/vt/schema/online_ddl.go:53

	onlineDdlUUIDRegexp               = regexp.MustCompile(`^[0-f]{8}_[0-f]{4}_[0-f]{4}_[0-f]{4}_[0-f]{12}$`)
	onlineDDLGeneratedTableNameRegexp = regexp.MustCompile(`^_[0-f]{8}_[0-f]{4}_[0-f]{4}_[0-f]{4}_[0-f]{12}_([0-9]{14})_(gho|ghc|del|new|vrepl)$`)
	ptOSCGeneratedTableNameRegexp     = regexp.MustCompile(`^_.*_old$`)
	migrationContextValidatorRegexp   = regexp.MustCompile(`^[\w:-]*$`)
)

var onlineDDLInternalTableHintsMap = map[string]bool{
	"vrp": true, // vreplication
	"gho": true, // gh-ost
	"ghc": true, // gh-ost
	"del": true, // gh-ost
	"new": true, // pt-osc
}

var (
	// ErrDirectDDLDisabled is returned when direct DDL is disabled, and a user attempts to run a DDL statement
	ErrDirectDDLDisabled = errors.New("direct DDL is disabled")
	// ErrOnlineDDLDisabled is returned when online DDL is disabled, and a user attempts to run an online DDL operation (submit, review, control)
	ErrOnlineDDLDisabled = errors.New("online DDL is disabled")
	// ErrForeignKeyFound indicates any finding of FOREIGN KEY clause in a DDL statement
	ErrForeignKeyFound = errors.New("Foreign key found")
	// ErrRenameTableFound indicates finding of ALTER TABLE...RENAME in ddl statement
	ErrRenameTableFound = errors.New("RENAME clause found")
)

const (
	SchemaMigrationsTableName = "schema_migrations"
	RevertActionStr           = "revert"
)

// ValidateMigrationContext validates that the given migration context only uses valid characters
func ValidateMigrationContext(migrationContext string) error {
	if migrationContextValidatorRegexp.MatchString(migrationContext) {
		return nil
	}
	return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid characters in migration_context %v. Use alphanumeric, dash, underscore and colon only", migrationContext)
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Enable online DDL by setting -ddl_strategy to an online strategy (gh-ost, pt-osc, or online) on the tablet
  2. If the operation must run now, use a direct strategy if permitted: /*vt+ ddl_strategy=direct */
  3. Verify the VReplication/online-DDL prerequisites are met on the target keyspace/tablets
  4. Handle errors.Is(err, schema.ErrOnlineDDLDisabled) in automation to pick a permitted strategy

Example fix

-- before (online-DDL disabled cluster)
ALTER /*vt+ ddl_strategy=gh-ost */ TABLE t ADD COLUMN c INT;
// after: enable it via tablet flag
-ddl_strategy gh-ost
-- or use direct if allowed
ALTER /*vt+ ddl_strategy=direct */ TABLE t ADD COLUMN c INT;
Defensive patterns

Strategy: validation

Validate before calling

strategy := viper.GetString("ddl_strategy")
if isOnlineDDLRequest(stmt) && !onlineDDLEnabled(strategy) {
    return fmt.Errorf("online DDL disabled; set ddl_strategy to gh-ost/pt-osc or use direct")
}

Try / catch

_, err := tm.TryExecute(ctx, migrationStmt)
if errors.Is(err, schema.ErrOnlineDDLDisabled) {
    return fmt.Errorf("online DDL is not enabled on this cluster: %w", err)
}

Prevention

When it happens

Trigger: Calling vtctldclient Migration... (submit/revert/show/logs) or issuing a /*vt+ ddl_strategy=online|gh-ost|pt-osc */ statement while the tablet's ddl_strategy/config disallows online DDL (e.g. set to 'direct' or online-DDL feature disabled).

Common situations: Clusters not provisioned for gh-ost/pt-osc (missing artifacts/binlog assumptions); operators restricting online DDL during maintenance windows; scripts reusing online-DDL syntax against a direct-only cluster.

Related errors


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