vitessio/vitess · error
no vdiff table found for %s on tablet %v
Error message
no vdiff table found for %s on tablet %v
What it means
When starting the diff, for each table in the plan vdiff queries the _vt.vdiff_table rows for this vdiff id. If no row exists for a table that is in the tableDiffers map, the internal state is inconsistent and this error is thrown before any diffing starts.
Source
Thrown at go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go:403
case <-ctx.Done():
return vterrors.Errorf(vtrpcpb.Code_CANCELED, "context has expired")
case <-wd.ct.done:
return ErrVDiffStoppedByUser
default:
}
query, err := sqlparser.ParseAndBind(sqlGetVDiffTable,
sqltypes.Int64BindVariable(wd.ct.id),
sqltypes.StringBindVariable(td.table.Name),
)
if err != nil {
return err
}
qr, err := dbClient.ExecuteFetch(query, 1)
if err != nil {
return err
}
if len(qr.Rows) == 0 {
return fmt.Errorf("no vdiff table found for %s on tablet %v",
td.table.Name, wd.ct.vde.thisTablet.Alias)
}
log.Info(fmt.Sprintf("Starting diff of table %s for vdiff %s", td.table.Name, wd.ct.uuid))
if err := wd.diffTable(ctx, dbClient, td); err != nil {
return wd.markTableErrored(ctx, dbClient, td, err)
}
if err := td.updateTableState(ctx, dbClient, CompletedState); err != nil {
return err
}
log.Info(fmt.Sprintf("Completed diff of table %s for vdiff %s", td.table.Name, wd.ct.uuid))
}
if err := wd.markIfCompleted(ctx, dbClient); err != nil {
return err
}
return nil
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Cancel the vdiff and start a fresh one (`CancelVExec`/`vd ct cancel` then re-run vdiff) so table rows are re-created
- Inspect `_vt.vdiff_table` on the target primary for the vdiff id and confirm which rows are missing
- Avoid manual deletes on _vt tables; if rows were removed, recreate the workflow's vdiff from scratch
- Ensure vtctld and tablets are on compatible Vitess versions during the vdiff
Example fix
// vtctlclient vtctldclient VDiff -- tabletspec ... cancel <keyspace> <workflow> vtctldclient VDiff -- ... show <keyspace> <workflow> # then re-run vdiff
Defensive patterns
Strategy: retry
Validate before calling
// check per-table state exists before resuming
qr, _ := dbClient.ExecuteFetch(fmt.Sprintf(
"SELECT 1 FROM _vt.vdiff_table WHERE vdiff_id=%d AND table_name='%s'", id, table), 1)
if len(qr.Rows) == 0 { // state missing: cancel and restart vdiff instead of resuming } Type guard
null
Try / catch
if err := wd.diff(ctx, dbClient); err != nil {
if strings.Contains(err.Error(), "no vdiff table found for") {
// cancel and start a fresh vdiff to rebuild per-table state
_ = wd.cancel(ctx)
return startFreshVDiff(ctx)
}
return err
} Prevention
- Don't manually delete rows from _vt.vdiff_table
- Run one vdiff at a time per workflow
- Cancel and re-run vdiff after any interruption of its creation
- Keep vtctld/tablets on compatible versions during a vdiff
When it happens
Trigger: A vdiff run whose expected per-table row in _vt.vdiff_table is missing on this tablet — e.g. the vdiff record was partially created, rows were deleted/cleaned concurrently, or the diff is being resumed against a tablet whose local vdiff state was wiped.
Common situations: Interruption during vdiff creation (vtctld crash between inserting the vdiff row and its table rows); manual cleanup of _vt.vdiff_table rows; running vdiff on a different target tablet than where state was created; upgrading Vitess mid-vdiff.
Related errors
- no state found for vdiff table %s for vdiff_id %d on tablet
- invalid state found for vdiff table %s (multiple records) fo
- invalid state found for vdiff table %s for vdiff_id %d on ta
- VDiff not implemented in vtcombo
- there are no cells in the topo
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b4f9f2904d6c8bdb.
Report an issue: GitHub.