vitessio/vitess · error

deferring secondary key creation is not supported for %s wor

Error message

deferring secondary key creation is not supported for %s workflows

What it means

stashSecondaryKeys drops secondary indexes before a table copy and re-creates them afterwards to speed up copying. This optimization is only supported for certain workflow types (checked via supportsDeferredSecondaryKeys). If invoked for an unsupported workflow, this error names the workflow type and aborts the key-deferral path.

Source

Thrown at go/vt/vttablet/tabletmanager/vreplication/vreplicator.go:788

	isPKMap := map[string]bool{}
	for i, colName := range uniqueKeyColumnNames {
		columnOrderMap[colName] = int64(i)
		isPKMap[colName] = true
	}
	sort.SliceStable(pkColInfos, func(i, j int) bool { return columnOrderMap[pkColInfos[i].Name] < columnOrderMap[pkColInfos[j].Name] })
	for i := range pkColInfos {
		pkColInfos[i].IsPK = isPKMap[pkColInfos[i].Name]
	}
	return pkColInfos
}

// stashSecondaryKeys temporarily DROPs all secondary keys from the table schema
// and stashes an ALTER TABLE statement that will be used to recreate them at the
// end of the copy phase.
func (vr *vreplicator) stashSecondaryKeys(ctx context.Context, tableName string) error {
	if !vr.supportsDeferredSecondaryKeys() {
		return fmt.Errorf("deferring secondary key creation is not supported for %s workflows",
			binlogdatapb.VReplicationWorkflowType_name[vr.WorkflowType])
	}
	secondaryKeys, err := vr.getTableSecondaryKeys(ctx, tableName)
	if err != nil {
		return err
	}
	if len(secondaryKeys) > 0 {
		alterDrop := &sqlparser.AlterTable{
			Table: sqlparser.TableName{
				Qualifier: sqlparser.NewIdentifierCS(vr.dbClient.DBName()),
				Name:      sqlparser.NewIdentifierCS(tableName),
			},
		}
		alterReAdd := &sqlparser.AlterTable{
			Table: sqlparser.TableName{
				Qualifier: sqlparser.NewIdentifierCS(vr.dbClient.DBName()),
				Name:      sqlparser.NewIdentifierCS(tableName),
			},

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify the workflow's type in _vt.vreplication (workflow_type column); only MoveTables/Reshard/Migrate-style workflows support deferred secondary keys.
  2. Upgrade Vitess if the workflow should be supported — support has been expanding across releases.
  3. Proceed without deferral: the copy will run with secondary indexes in place (slower but correct); no manual action needed for correctness.
  4. If copy speed is the concern, manually drop secondary indexes before the copy and re-add them after, outside the workflow machinery.
Defensive patterns

Strategy: fallback

Validate before calling

// Check the workflow type before expecting deferred secondary keys:
// SELECT workflow_type FROM _vt.vreplication WHERE id = <id>;
// Only MoveTables/Reshard/Migrate-style types support it.

Try / catch

if err := vr.stashSecondaryKeys(ctx, tableName); err != nil {
	log.Warn("secondary key deferral unsupported; copying with indexes in place", slog.Any("error", err))
	// fall back to normal copy path (correct, only slower)
}

Prevention

When it happens

Trigger: stashSecondaryKeys called (from initTablesForCopy or a post-copy callback) with vr.WorkflowType not in the supported set — e.g. legacy/custom workflows rather than MoveTables/Reshard/Migrate where deferral is implemented.

Common situations: Running a newer Vitess feature path against a workflow type that predates the optimization; custom or v2 workflows; workflows created before the feature existed and carrying a zero/unknown WorkflowType value.

Related errors


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