{"record":{"id":"1da34d7942748646","repo":"vitessio/vitess","slug":"w-progressfile-needs-to-be-empty-as-vitess-alw","errorCode":null,"errorMessage":"%w: \"progressFile\" needs to be empty as vitess always starts a restore from scratch","messagePattern":"%w: \"progressFile\" needs to be empty as vitess always starts a restore from scratch","errorType":"error_code","errorClass":"ErrMySQLShellPreCheck","httpStatus":null,"severity":"error","filePath":"go/vt/mysqlctl/mysqlshellbackupengine.go","lineNumber":515,"sourceCode":"}\n\nfunc (be *MySQLShellBackupEngine) restorePreCheck(ctx context.Context, params RestoreParams) (shouldDeleteUsers bool, err error) {\n\tif mysqlShellFlags == \"\" {\n\t\treturn shouldDeleteUsers, fmt.Errorf(\"%w: at least the --js flag is required in the value of the flag --mysql-shell-flags\", ErrMySQLShellPreCheck)\n\t}\n\n\tloadFlags := map[string]any{}\n\terr = json.Unmarshal([]byte(mysqlShellLoadFlags), &loadFlags)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"%w: unable to parse JSON of load flags\", ErrMySQLShellPreCheck)\n\t}\n\n\tif val, ok := loadFlags[\"updateGtidSet\"]; !ok || val != \"replace\" {\n\t\treturn false, fmt.Errorf(\"%w: mysql-shell needs to restore with updateGtidSet set to \\\"replace\\\" to work with Vitess\", ErrMySQLShellPreCheck)\n\t}\n\n\tif val, ok := loadFlags[\"progressFile\"]; !ok || val != \"\" {\n\t\treturn false, fmt.Errorf(\"%w: \\\"progressFile\\\" needs to be empty as vitess always starts a restore from scratch\", ErrMySQLShellPreCheck)\n\t}\n\n\tif val, ok := loadFlags[\"skipBinlog\"]; !ok || val != true {\n\t\treturn false, fmt.Errorf(\"%w: \\\"skipBinlog\\\" needs to set to true\", ErrMySQLShellPreCheck)\n\t}\n\n\tif val, ok := loadFlags[\"loadUsers\"]; ok && val == true {\n\t\tshouldDeleteUsers = true\n\t}\n\n\tif mysqlShellSpeedUpRestore {\n\t\tversion, err := params.Mysqld.GetVersionString(ctx)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"%w: failed to fetch MySQL version: %v\", ErrMySQLShellPreCheck, err)\n\t\t}\n\n\t\t_, sv, err := ParseVersionString(version)\n\t\tif err != nil {","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/mysqlshellbackupengine.go#L497-L533","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n\"loadFlags\": {\"updateGtidSet\": \"replace\", \"progressFile\": \"/tmp/load.progress\", \"skipBinlog\": true}\n// after\n\"loadFlags\": {\"updateGtidSet\": \"replace\", \"progressFile\": \"\", \"skipBinlog\": true}","handlingStrategy":"validation","validationCode":"flags, _ := loadFlags[\"progressFile\"]\nif v, ok := loadFlags[\"progressFile\"]; ok && v != \"\" {\n    return fmt.Errorf(\"mysql-shell loadFlags.progressFile must be empty for Vitess restores, got %v\", v)\n}","typeGuard":null,"tryCatchPattern":"// Go: detect the sentinel on restore failure\nif _, err := engine.ExecuteRestore(ctx, params, backupDir); err != nil {\n    if errors.Is(err, mysqlctl.ErrMySQLShellPreCheck) {\n        // fix loadFlags in backupengine config before retrying\n    }\n}","preventionTips":["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"],"tags":["mysql-shell","backup-restore","configuration"],"backgroundTag":"invalid-load-flags","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}