vitessio/vitess · error · errRestoreFatal
%w: %w
Error message
%w: %w
What it means
During builtin restore, failures in the setup phase are wrapped with errRestoreFatal using Go's multi-%w wrapping. Marking the error fatal tells the restore orchestrator to abort instead of retrying, since a setup failure means the restore cannot proceed at all. The second %w preserves the original cause for inspection.
Source
Thrown at go/vt/mysqlctl/builtinbackupengine.go:1518
for j := range fe.Chunks {
workItems = append(workItems, restoreWorkItem{
fe: fe,
chunk: &fe.Chunks[j],
destPath: fullPath,
name: fe.Chunks[j].StorageName,
})
}
} else {
workItems = append(workItems, restoreWorkItem{
fe: fe,
name: strconv.Itoa(i),
})
}
}
if setupErr != nil {
return fmt.Errorf("%w: %w", errRestoreFatal, setupErr)
}
// Phase 2: Dispatch all work items concurrently.
for _, wi := range workItems {
if ctx.Err() != nil {
break
}
g.Go(func() error {
select {
case <-ctx.Done():
params.Logger.Errorf("Context canceled or timed out during %q restore", wi.fe.Name)
bh.RecordError(wi.name, vterrors.Errorf(vtrpcpb.Code_CANCELED, "context canceled"))
return nil
default:
}
var err error
if wi.chunk != nil {View on GitHub (pinned to 01a25a7d17)
Solutions
- Read the wrapped cause after the colon — it names the actual setup step that failed.
- Fix the underlying setup problem (manifest, mysqld shutdown, data dir permissions).
- Do not simply retry: fatal errors are fatal because the local state is not restore-safe.
- If the cause is a manifest problem, verify the backup is complete or pick an earlier backup.
Defensive patterns
Strategy: try-catch
Try / catch
err := tabletmanager.RestoreData(ctx, ...)
if err != nil {
if errors.Is(err, errRestoreFatal) {
// abort: do not retry, fix the reported cause first
return err
}
// non-fatal: retry may succeed
} Prevention
- Take backups only after verifying the source tablet is healthy.
- Ensure backup storage is reachable and manifests are complete before restore.
- Watch for setup-phase logs; failures there are always fatal by design.
When it happens
Trigger: RestoreFromBackup reaches the end of phase 1 with a non-nil setupErr — e.g. failure to stop mysqld, prepare the data directory, or fetch/validate backup manifest before work items are dispatched.
Common situations: Corrupt or incomplete backup manifest in the backup storage; mysqld refusing to shut down within timeout; data directory permission problems on the tablet host.
Related errors
- cannot use backup between different flavors: %q vs. %q
- running MySQL version %q is newer than backup MySQL version
- running MySQL version %q is older than backup MySQL version
- running MySQL version %q is too new for backup MySQL version
- %w %q
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/42fbe876286a3cc6.
Report an issue: GitHub.