vitessio/vitess · error
running MySQL version %q is too new for backup MySQL version
Error message
running MySQL version %q is too new for backup MySQL version %q
What it means
Thrown when the backup and running versions sit in the LTS upgrade-path walk but the running version goes beyond the allowed next-LTS target. The loop found parsedFrom in ltsVersions, parsedTo is not the immediately next LTS entry, and parsedTo >= parsedFrom, so the restore is rejected as 'too new'.
Source
Thrown at go/vt/mysqlctl/backupengine.go:703
// If something is across different LTS streams and not upgrade safe, we can't use it.
if !parsedFrom.isSameRelease(parsedTo) {
if !upgradeSafe {
if parsedTo.atLeast(parsedFrom) {
return fmt.Errorf("running MySQL version %q is newer than backup MySQL version %q which is not safe to upgrade", to, from)
}
return fmt.Errorf("running MySQL version %q is older than backup MySQL version %q", to, from)
}
// Alright, we're across different LTS streams and the backup is upgrade safe.
// We can only upgrade to the next LTS version.
for i, ltsVersion := range ltsVersions {
if parsedFrom.isSameRelease(ltsVersion) {
if i < len(ltsVersions)-1 && parsedTo.isSameRelease(ltsVersions[i+1]) {
return nil
}
if parsedTo.atLeast(parsedFrom) {
return fmt.Errorf("running MySQL version %q is too new for backup MySQL version %q", to, from)
}
return fmt.Errorf("running MySQL version %q is older than backup MySQL version %q", to, from)
}
}
if parsedTo.atLeast(parsedFrom) {
return fmt.Errorf("running MySQL version %q is newer than backup MySQL version %q which is not safe to upgrade", to, from)
}
return fmt.Errorf("running MySQL version %q is older than backup MySQL version %q", to, from)
}
// At this point we know the versions are not the same, but we're withing the same version stream
// and only the patch version number mismatches.
// Starting with MySQL 8.0.35, the data dictionary format is stable for 8.0.x, so we can upgrade
// from 8.0.35 or later here, also if the backup was taken with innodb_fast_shutdown=0.
// This also applies for any version newer like 8.4.x.
if parsedFrom.atLeast(mysql8035) && parsedTo.atLeast(mysql8035) {
return nilView on GitHub (pinned to 01a25a7d17)
Solutions
- Restore onto a tablet running the immediately next LTS version after the backup's version, then upgrade stepwise (restore -> upgrade -> next).
- Take a new backup on a version that is upgrade-safe for the desired target and restore from that.
- Pin the tablet's MySQL version to one covered by the backup's upgrade path.
- Plan upgrades against vitess's ltsVersions list and MySQL's supported in-place upgrade paths.
Example fix
// before: 8.0.x backup restored directly onto latest 8.4/9.x -> 'too new' // after: restore onto next LTS first, then stepwise upgrade and re-backup
Defensive patterns
Strategy: validation
Validate before calling
if skippingLTS(backupVer, runningVer) {
return errors.New("restore path skips an LTS: restore stepwise or retake backup")
} Prevention
- Never skip LTS versions during upgrades; restore/upgrade one LTS at a time.
- Retake backups after each LTS upgrade step.
- Plan MySQL upgrades against supported in-place upgrade paths.
When it happens
Trigger: Restore where parsedFrom matches an ltsVersions entry, parsedTo is not the immediate next LTS entry (i+1), and parsedTo.atLeast(parsedFrom) — e.g. skipping an LTS by restoring an older-LTS backup onto a tablet two or more LTS streams ahead.
Common situations: Skipping LTS versions during upgrade (8.0 backup restored straight to a far-newer LTS); rebuilt tablet configured with a much newer mysqld than the backup.
Related errors
- running MySQL version %q is newer than backup MySQL version
- running MySQL version %q is older than backup MySQL version
- mysqld >= 8.0.21 required to disable the redo log
- cannot use backup between different flavors: %q vs. %q
- cannot determine database flavor details for version %s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/f7e5146697a6a5ce.
Report an issue: GitHub.