vitessio/vitess · warning
%v has an extra %v %v
Error message
%v has an extra %v %v
What it means
diffPermissions compares two Permission sets (left vs right) by sorted primary key. When the left side contains a permission entry (a user or a table in a permission record) that the right side lacks, this error records a drift on the left (leftName).
Source
Thrown at go/vt/mysqlctl/tmutils/permissions.go:178
return result
}
// PermissionsString pretty-prints Permissions
func PermissionsString(permissions *tabletmanagerdatapb.Permissions) string {
return printPermissions("User", userPermissionList(permissions.UserPermissions)) +
printPermissions("Db", dbPermissionList(permissions.DbPermissions))
}
func diffPermissions(name, leftName string, left permissionList, rightName string, right permissionList, er concurrency.ErrorRecorder) {
leftIndex := 0
rightIndex := 0
for leftIndex < left.Len() && rightIndex < right.Len() {
lpk, lval := left.Get(leftIndex)
rpk, rval := right.Get(rightIndex)
// extra value on the left side
if lpk < rpk {
er.RecordError(fmt.Errorf("%v has an extra %v %v", leftName, name, lpk))
leftIndex++
continue
}
// extra value on the right side
if lpk > rpk {
er.RecordError(fmt.Errorf("%v has an extra %v %v", rightName, name, rpk))
rightIndex++
continue
}
// same name, let's see content
if lval != rval {
er.RecordError(fmt.Errorf("permissions differ on %v %v:\n%s: %v\n differs from:\n%s: %v", name, lpk, leftName, lval, rightName, rval))
}
leftIndex++
rightIndex++
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Diff the permission lists on both sides and apply the missing/extra GRANT/REVOKE so both match
- Re-sync permissions from the source of truth (topo or target tablet)
- Check for manual GRANT statements run on only one MySQL instance
- Re-run DiffPermissions to confirm drift is resolved
Example fix
// before: manual GRANT on left tablet only // after: apply the same GRANT on both, or REVOKE on left // REVOKE ... ON db.* FROM 'user'@'host';
Defensive patterns
Strategy: validation
Validate before calling
// compare permission key sets before invoking diff
leftKeys, rightKeys := keySet(left), keySet(right)
for k := range leftKeys {
if !rightKeys[k] {
log.Warnf("left has extra permission %v; will be flagged", k)
}
} Try / catch
er := tmutils.DiffPermissions("local", permsLocal, "topo", permsTopo)
if er.HasErrors() {
for _, err := range er.Errors {
log.Warn("permission drift detected", slog.Any("error", err))
}
} Prevention
- Apply GRANT/REVOKE changes to all tablets uniformly
- Use the topo as the source of truth for permissions
- Audit manual dbadmin GRANTs after incidents
When it happens
Trigger: Running DiffPermissions (tablet-manager permission sync/checks) when the left source (e.g. local mysqld) has an extra user/DB/table permission entry absent from the right (e.g. expected topo copy).
Common situations: A GRANT was applied directly on one tablet but not replicated to the other; permissions drift after manual dbadmin operations; comparing freshly-restored tablets against topo records.
Related errors
- schemas differ on table type for table %v: %s: %v differs f
- ReadFile cannot be called on read-write backup
- AddFile cannot be called on read-only backup
- EndBackup cannot be called on read-only backup
- AbortBackup cannot be called on read-only backup
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/6471c3139b5ad266.
Report an issue: GitHub.