vitessio/vitess · error

vdiff with UUID %s already exists on tablet %s

Error message

vdiff with UUID %s already exists on tablet %s

What it means

handleCreateResumeAction rejects a CreateAction when a vdiff record with the requested UUID already exists in _vt.vdiff_tablet on that tablet. Vitess requires unique UUIDs per tablet to avoid clobbering in-progress diff state.

Source

Thrown at go/vt/vttablet/tabletmanager/vdiff/action.go:197

	return strings.Join(cells, ","), nil
}

func (vde *Engine) handleCreateResumeAction(ctx context.Context, dbClient binlogplayer.DBClient, action VDiffAction, req *tabletmanagerdatapb.VDiffRequest, resp *tabletmanagerdatapb.VDiffResponse) error {
	var qr *sqltypes.Result
	options := req.GetOptions()

	query, err := sqlparser.ParseAndBind(sqlGetVDiffID, sqltypes.StringBindVariable(req.VdiffUuid), sqltypes.StringBindVariable(vde.dbName))
	if err != nil {
		return err
	}
	if qr, err = dbClient.ExecuteFetch(query, 1); err != nil {
		return err
	}
	recordFound := len(qr.Rows) == 1

	if action == CreateAction {
		if recordFound {
			return fmt.Errorf("vdiff with UUID %s already exists on tablet %s",
				req.VdiffUuid, topoproto.TabletAliasString(vde.thisTablet.Alias))
		}
		// Use the options specified via the vdiff create client
		// command, which we'll then store in the vdiff record.
		if options, err = vde.fixupOptions(options); err != nil {
			return err
		}
		optionsJSON, err := json.Marshal(options)
		if err != nil {
			return err
		}
		state := PendingState
		if options.CoreOptions != nil && options.CoreOptions.AutoStart != nil && !options.CoreOptions.GetAutoStart() {
			state = StoppedState
		}
		query, err := sqlparser.ParseAndBind(sqlNewVDiff,
			sqltypes.StringBindVariable(req.Keyspace),
			sqltypes.StringBindVariable(req.Workflow),

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. If you want to continue, use resume instead of create (vdiff resume) for the existing UUID
  2. Delete the existing vdiff first: vtctldclient VDiff delete and then re-create
  3. Pick a new unique UUID for the new comparison
  4. List current vdiffs with vdiff show to confirm which UUIDs exist

Example fix

// before
vtctldclient VDiff --keyspace c --workflow w create --tablet-uuid fixed-uuid
// after
vtctldclient VDiff --keyspace c --workflow w delete --tablet-uuid fixed-uuid
vtctldclient VDiff --keyspace c --workflow w create --tablet-uuid fixed-uuid
Defensive patterns

Strategy: validation

Validate before calling

qr, _ := dbClient.ExecuteFetch("SELECT uuid FROM _vt.vdiff_tablet WHERE uuid=?", 1, true) // bind uuid
if len(qr.Rows) > 0 { // already exists: resume or delete instead of create }

Try / catch

if strings.Contains(err.Error(), "already exists on tablet") {
    // fall back to resume, or delete then re-create
}

Prevention

When it happens

Trigger: Running `vdiff create --tablet-uuid <uuid>` (or workflow VDiff create) when a previous vdiff with the same UUID was already created on this tablet and not deleted.

Common situations: Re-running an interrupted vdiff create without deleting the old record; scripted retries that reuse a fixed UUID; resuming vs creating confusion — the workflow already exists and should be resumed, not created.

Related errors


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