vitessio/vitess · error · ErrMySQLShellPreCheck
%w: "progressFile" needs to be empty as vitess always starts
Error message
%w: "progressFile" needs to be empty as vitess always starts a restore from scratch
What it means
restorePreCheck in the MySQL Shell backup engine validates the `loadFlags` configured for mysql-shell's load dump utility. Vitess always restores from scratch, so a progress file (which enables resuming a partial load) is not supported. This error is wrapped with ErrMySQLShellPreCheck so callers can detect pre-check failures.
Source
Thrown at go/vt/mysqlctl/mysqlshellbackupengine.go:515
}
func (be *MySQLShellBackupEngine) restorePreCheck(ctx context.Context, params RestoreParams) (shouldDeleteUsers bool, err error) {
if mysqlShellFlags == "" {
return shouldDeleteUsers, fmt.Errorf("%w: at least the --js flag is required in the value of the flag --mysql-shell-flags", ErrMySQLShellPreCheck)
}
loadFlags := map[string]any{}
err = json.Unmarshal([]byte(mysqlShellLoadFlags), &loadFlags)
if err != nil {
return false, fmt.Errorf("%w: unable to parse JSON of load flags", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["updateGtidSet"]; !ok || val != "replace" {
return false, fmt.Errorf("%w: mysql-shell needs to restore with updateGtidSet set to \"replace\" to work with Vitess", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["progressFile"]; !ok || val != "" {
return false, fmt.Errorf("%w: \"progressFile\" needs to be empty as vitess always starts a restore from scratch", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["skipBinlog"]; !ok || val != true {
return false, fmt.Errorf("%w: \"skipBinlog\" needs to set to true", ErrMySQLShellPreCheck)
}
if val, ok := loadFlags["loadUsers"]; ok && val == true {
shouldDeleteUsers = true
}
if mysqlShellSpeedUpRestore {
version, err := params.Mysqld.GetVersionString(ctx)
if err != nil {
return false, fmt.Errorf("%w: failed to fetch MySQL version: %v", ErrMySQLShellPreCheck, err)
}
_, sv, err := ParseVersionString(version)
if err != nil {View on GitHub (pinned to 01a25a7d17)
Solutions
- Remove the "progressFile" entry from loadFlags in the backupengine mysqlshell config, or set it to an empty string
- Review the other mandatory loadFlags: updateGtidSet must be "replace" and skipBinlog must be true
- If resumable loads are needed, do not use the mysql-shell engine; restore is always started from scratch under Vitess
Example fix
// before
"loadFlags": {"updateGtidSet": "replace", "progressFile": "/tmp/load.progress", "skipBinlog": true}
// after
"loadFlags": {"updateGtidSet": "replace", "progressFile": "", "skipBinlog": true} Defensive patterns
Strategy: validation
Validate before calling
flags, _ := loadFlags["progressFile"]
if v, ok := loadFlags["progressFile"]; ok && v != "" {
return fmt.Errorf("mysql-shell loadFlags.progressFile must be empty for Vitess restores, got %v", v)
} Try / catch
// Go: detect the sentinel on restore failure
if _, err := engine.ExecuteRestore(ctx, params, backupDir); err != nil {
if errors.Is(err, mysqlctl.ErrMySQLShellPreCheck) {
// fix loadFlags in backupengine config before retrying
}
} Prevention
- Keep loadFlags for the mysql-shell engine minimal: only updateGtidSet=replace and skipBinlog=true
- Do not copy resumable-load examples with --progress-file into Vitess configs
- Validate the backupengine config once at deploy time instead of at restore time
When it happens
Trigger: Calling MySQLShellBackupEngine.ExecuteRestore (via restorePreCheck) when the backupengine's `loadFlags` map contains "progressFile" with any non-empty value, or when the key is absent and the default in the config template is not overridden to empty.
Common situations: Operators copy a mysql-shell load command example that uses `--progress-file=load.progress` for resumable loads into the Vitess `loadFlags` setting; existing flags from a non-Vitess mysql-shell workflow are reused without removing progressFile.
Related errors
- %w: "skipBinlog" needs to set to true
- %w: failed to fetch MySQL version: %v
- %w: failed to parse MySQL version (version: %s): %v
- %w: error checking if server supports disabling redo log: %v
- %w: MySQL version doesn't support disabling the redo log (mu
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/1da34d7942748646.
Report an issue: GitHub.