{"record":{"id":"9ad7b6ef94aff587","repo":"vitessio/vitess","slug":"cannot-use-backup-between-different-flavors-q-vs","errorCode":null,"errorMessage":"cannot use backup between different flavors: %q vs. %q","messagePattern":"cannot use backup between different flavors: %q vs\\. %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/mysqlctl/backupengine.go","lineNumber":675,"sourceCode":"\nfunc validateMySQLVersionUpgradeCompatible(to string, from string, upgradeSafe bool) error {\n\t// It's always safe to use the same version.\n\tif to == from {\n\t\treturn nil\n\t}\n\n\tflavorTo, parsedTo, err := ParseVersionString(to)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tflavorFrom, parsedFrom, err := ParseVersionString(from)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif flavorTo != flavorFrom {\n\t\treturn fmt.Errorf(\"cannot use backup between different flavors: %q vs. %q\", from, to)\n\t}\n\n\tif parsedTo == parsedFrom {\n\t\treturn nil\n\t}\n\n\t// If we're not on the same LTS stream, we have to do additional checks to see if it's safe to\n\t// to upgrade. It can only be one newer LTS version for the destination and the backup\n\t// has to be marked as upgrade safe.\n\n\t// If something is across different LTS streams and not upgrade safe, we can't use it.\n\tif !parsedFrom.isSameRelease(parsedTo) {\n\t\tif !upgradeSafe {\n\t\t\tif parsedTo.atLeast(parsedFrom) {\n\t\t\t\treturn fmt.Errorf(\"running MySQL version %q is newer than backup MySQL version %q which is not safe to upgrade\", to, from)\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"running MySQL version %q is older than backup MySQL version %q\", to, from)\n\t\t}","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/backupengine.go#L657-L693","documentation":"The MySQL backup engine validates that a backup taken on one flavor (e.g. MySQL vs MariaDB vs Percona) can only be restored on the same flavor. This error comes from the compatibility check comparing the 'from' and 'to' version strings; restoring across flavors is unsupported because data layout, redo/inno formats, and utilities differ.","triggerScenarios":"Calling restore (e.g. RestoreData / backupengine restore path) with from=\"MariaDB10.6\" and to=\"MySQL8.0\" (or vice versa); also occurs when a tablet's mysqld was upgraded/replaced with a different flavor while old backups exist.","commonSituations":"Migrating a cluster between MySQL and Percona/MariaDB, provisioning mistakes where new tablets run a different flavor than the one used to take backups, mistaken mysqld version configuration in vttablet/vtctld.","solutions":["Provision the restore target with the same MySQL flavor as the backup.","Take a fresh backup using the new flavor and restore from that instead.","If flavor migration is truly needed, do a logical migration (export/import) rather than a binary restore.","Fix version config so the correct from/to flavor strings are passed (check ParseVersionString inputs)."],"exampleFix":"// before\n// restore backup from=\"MySQL8.0.35\" onto to=\"MariaDB10.6\"\n// returns: cannot use backup between different flavors\n// after\n// restore onto to=\"MySQL8.0.35\" (same flavor), or take a new backup on MariaDB first","handlingStrategy":"validation","validationCode":"fromFlavor, _, err := mysqlctl.ParseVersionString(from)\nif err != nil {\n\treturn err\n}\ntoFlavor, _, err := mysqlctl.ParseVersionString(to)\nif err != nil {\n\treturn err\n}\nif fromFlavor != toFlavor {\n\treturn fmt.Errorf(\"backup flavor %q != target flavor %q\", from, to)\n}","typeGuard":null,"tryCatchPattern":"err := engine.RestoreData(ctx, h, bh, localMetadata, dir, restartMySql)\nif err != nil && strings.Contains(err.Error(), \"different flavors\") {\n\treturn fmt.Errorf(\"take a fresh backup on the target flavor: %w\", err)\n}","preventionTips":["Keep the mysqld flavor consistent across the cluster and backup targets","After a flavor migration, take fresh backups before allowing restores","Verify version strings with mysqlctl.ParseVersionString in provisioning checks"],"tags":["go","backup","mysql","flavor-mismatch","restore"],"backgroundTag":"mysql-flavor-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}