vitessio/vitess · error
schemas differ on table %v: %s: %v differs from: %s: %v
Error message
schemas differ on table %v: %s: %v differs from: %s: %v
What it means
When both tablets have a table with the same name but the CREATE TABLE / view definition string differs, DiffSchema records this error showing each side's table schema. Internal operation tables are skipped. This is the core table-level schema drift detection used by vtctldclient Schema Diff workflows.
Source
Thrown at go/vt/mysqlctl/tmutils/schema.go:252
er.RecordError(fmt.Errorf("%v has an extra table named %v", leftName, left.TableDefinitions[leftIndex].Name))
}
leftIndex++
continue
}
// extra table on the right side
if left.TableDefinitions[leftIndex].Name > right.TableDefinitions[rightIndex].Name {
if !schema.IsInternalOperationTableName(right.TableDefinitions[rightIndex].Name) {
er.RecordError(fmt.Errorf("%v has an extra table named %v", rightName, right.TableDefinitions[rightIndex].Name))
}
rightIndex++
continue
}
// same name, let's see content
if left.TableDefinitions[leftIndex].Schema != right.TableDefinitions[rightIndex].Schema {
if !schema.IsInternalOperationTableName(left.TableDefinitions[leftIndex].Name) {
er.RecordError(fmt.Errorf("schemas differ on table %v:\n%s: %v\n differs from:\n%s: %v", left.TableDefinitions[leftIndex].Name, leftName, left.TableDefinitions[leftIndex].Schema, rightName, right.TableDefinitions[rightIndex].Schema))
}
}
if left.TableDefinitions[leftIndex].Type != right.TableDefinitions[rightIndex].Type {
if !schema.IsInternalOperationTableName(right.TableDefinitions[rightIndex].Name) {
er.RecordError(fmt.Errorf("schemas differ on table type for table %v:\n%s: %v\n differs from:\n%s: %v", left.TableDefinitions[leftIndex].Name, leftName, left.TableDefinitions[leftIndex].Type, rightName, right.TableDefinitions[rightIndex].Type))
}
}
leftIndex++
rightIndex++
}
for leftIndex < len(left.TableDefinitions) {
if left.TableDefinitions[leftIndex].Type == TableBaseTable {
if !schema.IsInternalOperationTableName(left.TableDefinitions[leftIndex].Name) {
er.RecordError(fmt.Errorf("%v has an extra table named %v", leftName, left.TableDefinitions[leftIndex].Name))
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Apply the correct ALTER TABLE (or CREATE VIEW) on the lagging tablet so the definitions match
- Use vtctldclient ApplySchema / controlled replication catch-up to propagate the DDL
- Run an online schema change tool across all shards to converge the schema
- Re-run the schema diff afterward to confirm zero differences
Example fix
// before -- tablet A: orders has column `note VARCHAR(100)` -- tablet B: orders lacks `note` // after (on tablet B's MySQL) ALTER TABLE orders ADD COLUMN note VARCHAR(100);
Defensive patterns
Strategy: validation
Validate before calling
for i, lt := range left.TableDefinitions {
for _, rt := range right.TableDefinitions {
if lt.Name == rt.Name && lt.Schema != rt.Schema {
log.Warn("table schema drift", slog.String("table", lt.Name), slog.String("left", lt.Schema), slog.String("right", rt.Schema))
}
}
_ = i
} Try / catch
er := concurrency.AllErrorRecorder{}
tmutils.DiffSchema("left", left, "right", right, &er)
if er.HasErrors() {
return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "table schema drift: %w", er.Error())
}
// proceed only when schemas are identical Prevention
- Always apply DDL through vtctldclient ApplySchema for atomic, tracked migrations
- Run a schema diff before and after every migration as a gate
- Keep all shards on the same migration sequence (use online DDL with consistent start)
- Monitor replication so DDL never silently skips a tablet
When it happens
Trigger: DiffSchema compares two TableDefinitions with equal names where left.Schema != right.Schema — different columns, indexes, charsets, or view definitions between tablets.
Common situations: A migration/ALTER TABLE was applied on the primary but a replica missed it; schema applied out of order across shards; manual column addition on one tablet; a view redefined on only one side.
Related errors
- schemas are different: %s: %v, %s: %v
- schemas are different: %s: %v differs from: %s: %v
- %v has an extra table named %v
- permissions differ on %v %v: %s: %v differs from: %s: %v
- schema looks incorrect: %s, expecting at least four lines
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/ef340519c55f5b07.
Report an issue: GitHub.