benbjohnson/litestream · critical
restore from backup: %w
Error message
restore from backup: %w
What it means
DB.EnsureExists(ctx) attempts to restore the database from the replica via db.Replica.Restore(ctx, opt). If the restore fails with anything other than ErrTxNotAvailable or ErrNoSnapshots (which mean "no backup yet" and are treated as fresh-start), litestream wraps the error as "restore from backup". The database is NOT usable until this is resolved.
Source
Thrown at db.go:762
return fmt.Errorf("stat database: %w", err)
}
if dir := filepath.Dir(db.Path()); dir != "." {
if err := os.MkdirAll(dir, 0o750); err != nil {
return fmt.Errorf("create parent directory: %w", err)
}
}
opt := NewRestoreOptions()
opt.OutputPath = db.Path()
opt.IntegrityCheck = IntegrityCheckQuick
if err := db.Replica.Restore(ctx, opt); err != nil {
if errors.Is(err, ErrTxNotAvailable) || errors.Is(err, ErrNoSnapshots) {
db.Logger.Debug("no backup found, will create fresh database")
return nil
}
return fmt.Errorf("restore from backup: %w", err)
}
db.Logger.Info("database restored from backup", "path", db.Path())
return nil
}
// Open initializes the background monitoring goroutine.
func (db *DB) Open() (err error) {
db.mu.Lock()
if db.opened {
db.mu.Unlock()
return nil // already open
}
// Recreate context for fresh start (handles reopen after close)
db.ctx, db.cancel = context.WithCancel(context.Background())
db.mu.Unlock()
// Validate fields on database.View on GitHub (pinned to 4ed7a308f6)
Solutions
- Unwrap the error to see whether the failure was remote fetch, write, or integrity check.
- Inspect the replica contents with `litestream ltx -level all` to verify the LTX chain and snapshots are intact.
- Verify read (GetObject) permissions and network access to the replica destination, then retry the restore.
- If remote state is corrupted/unusable and you accept data loss, remove/renaming the replica path and start fresh (a new DB will be created on Open()) — otherwise repair from another replica copy.
Example fix
// before
if err := db.EnsureExists(ctx); err != nil {
log.Fatal(err) // opaque "restore from backup: ..."
}
// after
if err := db.EnsureExists(ctx); err != nil {
if errors.Is(err, litestream.ErrTxNotAvailable) {
// no backup yet: fresh DB will be created
} else {
log.Fatalf("restore failed: %v", err) // inspect wrapped cause
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: read access to the replica before attempting restore // e.g. run `litestream ltx -level all` against the replica and fail fast if unreadable
Try / catch
if err := db.EnsureExists(ctx); err != nil {
switch {
case errors.Is(err, litestream.ErrTxNotAvailable), errors.Is(err, litestream.ErrNoSnapshots):
// treat as fresh start
default:
return fmt.Errorf("restore from backup failed: %w", err)
}
} Prevention
- Do not let cloud lifecycle policies delete LTX files still needed for restore.
- Grant GetObject (read) in addition to list permissions on the replica prefix.
- Periodically run test restores (litestream restore to a scratch dir) to validate the backup.
- Ensure the restore output path is writable and integrity check settings match your data size.
When it happens
Trigger: Replica.Restore failing during the local restore: remote LTX fetch failures (network/credentials), integrity check failure (opt.IntegrityCheck = IntegrityCheckQuick), corrupted remote LTX files, or unsupported/failed output write to db.Path().
Common situations: Remote replica truncated or corrupted by lifecycle rules; network interruption mid-restore; restore target path unwritable; quick integrity check failing because the latest LTX chain is inconsistent; provider credentials valid for listing but not for GetObject.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- no snapshots available
- no replica client configured
- remote position: %w
- list generations: %w
- list snapshots for generation %s: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/691404bd4ae05041.
Report an issue: GitHub.