vitessio/vitess · error
type PRIMARY cannot restore from backup, if you really need
Error message
type PRIMARY cannot restore from backup, if you really need to do this, restart vttablet in replica mode
What it means
RestoreFromBackup refuses to run on a tablet the topology reports as PRIMARY, since restoring would wipe/replace a serving primary's data. The error directs you to restart the tablet as a replica type before restoring.
Source
Thrown at go/vt/vttablet/tabletmanager/rpc_backup.go:220
defer func() {
if startTime.IsZero() {
return
}
tm.QueryServiceControl.BroadcastHealth()
tm.invokeRestoreDoneHook(startTime, restoreErr, backupEngine)
}()
if err := tm.lock(ctx); err != nil {
return err
}
defer tm.unlock()
tablet, err := tm.TopoServer.GetTablet(ctx, tm.tabletAlias)
if err != nil {
return err
}
if tablet.Type == topodatapb.TabletType_PRIMARY {
return errors.New("type PRIMARY cannot restore from backup, if you really need to do this, restart vttablet in replica mode")
}
// Create the logger: tee to console and source.
l := logutil.NewTeeLogger(logutil.NewConsoleLogger(), logger)
// Now we can run restore.
startTime = time.Now()
backupEngine, restoreErr = tm.restoreBackupLocked(ctx, l, 0 /* waitForBackupInterval */, true /* deleteBeforeRestore */, request, mysqlShutdownTimeout)
return restoreErr
}
func (tm *TabletManager) IsBackupRunning() bool {
return tm._isBackupRunning
}
func (tm *TabletManager) beginBackup(backupMode string) error {
tm.mutex.Lock()View on GitHub (pinned to 01a25a7d17)
Solutions
- Demote/remove the tablet from primary duty (reparent to another tablet) first
- Restart vttablet in REPLICA type (edit the type in topo or start with the appropriate type) and then run the restore
- Verify with vtctldclient GetTablets that the target is no longer PRIMARY before restoring
Example fix
// before vtctldclient RestoreFromBackup alias-1 # alias-1 is PRIMARY // after vtctldclient PlannedReparentShard ks -new-primary alias-2 # restart alias-1 as replica, then: vtctldclient RestoreFromBackup alias-1
Defensive patterns
Strategy: validation
Validate before calling
tablet, err := ts.GetTablet(ctx, alias)
if err != nil { return err }
if tablet.Type == topodatapb.TabletType_PRIMARY {
return fmt.Errorf("cannot restore %s: demote/restart as replica first", topoproto.TabletAliasString(alias))
} Try / catch
err := tm.RestoreFromBackup(ctx, logger)
if err != nil && strings.Contains(err.Error(), "cannot restore from backup") {
return fmt.Errorf("tablet is PRIMARY in topo; reparent then restart as replica before restore")
} Prevention
- Gate restore automation on a non-PRIMARY topo type check
- Include tablet type in restore runbooks and preflight checks
- After emergency promotion, rebuild old primaries as replicas before any restore
When it happens
Trigger: Calling RestoreFromBackup (vtctldclient RestoreFromBackup) against a tablet whose topo record has Type PRIMARY.
Common situations: Restoring a tablet that was accidentally promoted; emergency restore tooling pointed at the wrong alias; primary tablet being rebuilt without first being demoted/restarted as replica.
Related errors
- type PRIMARY cannot take backup. if you really need to do th
- BeforeSchema differs
- AfterSchema differs
- no primary tablet found
- must be non-negative
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/7ca3846085022c7b.
Report an issue: GitHub.