vitessio/vitess · error
running MySQL version %q is older than backup MySQL version
Error message
running MySQL version %q is older than backup MySQL version %q
What it means
Thrown by checkRestoreVersion when the running MySQL version is older than the version the backup was taken with, across different release streams, and the backup is not upgrade-safe. Downgrading across release streams by restoring newer data files onto an older MySQL binary is unsupported, so the restore is aborted.
Source
Thrown at go/vt/mysqlctl/backupengine.go:692
if flavorTo != flavorFrom {
return fmt.Errorf("cannot use backup between different flavors: %q vs. %q", from, to)
}
if parsedTo == parsedFrom {
return nil
}
// If we're not on the same LTS stream, we have to do additional checks to see if it's safe to
// to upgrade. It can only be one newer LTS version for the destination and the backup
// has to be marked as upgrade safe.
// 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)
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Upgrade the tablet's mysqld to a version at least as new as the backup's MySQL version, then restore.
- Take a fresh backup from a tablet running the older MySQL version and restore from that.
- Align the fleet on one MySQL release stream so backups and tablets match.
- Check the backup manifest's MySQLVersion for mis-recording if versions were expected to match.
Example fix
// before: 8.4.2 backup, tablet on 8.0.36 -> error // after: upgrade tablet mysqld to 8.4.2 (>= backup version) and restore
Defensive patterns
Strategy: validation
Validate before calling
backupVer := parseVersion(backupManifest.MySQLVersion)
runningVer := parseVersion(getRunningMySQLVersion())
if !runningVer.atLeast(backupVer) {
return errors.New("tablet MySQL older than backup version: upgrade tablet or use older backup")
} Prevention
- Provision tablets with MySQL >= the version used for the backups they will restore.
- Avoid rolling back MySQL upgrades while recent backups are the restore candidates.
- Audit fleet MySQL versions against latest backup versions regularly.
When it happens
Trigger: Restore where parsedTo.atLeast(parsedFrom) is false (running version strictly older than backup version), versions are not same-release, and the backup manifest lacks the upgrade-safe marker.
Common situations: A tablet was provisioned with an older MySQL than the one used to produce the backup (e.g. backup from 8.4.x, tablet runs 8.0.y); mixed versions after a partial rollout/rollback of a MySQL upgrade.
Related errors
- running MySQL version %q is newer than backup MySQL version
- running MySQL version %q is too new for 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/02c99dae62a641dd.
Report an issue: GitHub.