ory/hydra · error
backup.Step failed
Error message
backup.Step failed
What it means
Returned during SQLite online restore when backup.Step(-1), which copies all remaining pages from the source database, fails. The underlying error comes from the SQLite backup API — source database locked, I/O error, or corrupt source — and Finish is called before returning.
Source
Thrown at oryx/popx/migrator.go:115
driverConn = w.Raw()
}
restorer, ok := driverConn.(interface {
NewRestore(srcUri string) (*moderncsqlite.Backup, error)
})
if !ok {
return errors.Errorf("driver %T does not support online restore", driverConn)
}
// See: https://sqlite.org/backup.html .
backup, err := restorer.NewRestore(srcPath)
if err != nil {
return errors.Wrap(err, "NewRestore failed")
}
// Step(-1) copies all remaining pages in one call.
for {
more, stepErr := backup.Step(-1)
if stepErr != nil {
_ = backup.Finish()
return errors.Wrap(stepErr, "backup.Step failed")
}
if !more {
break
}
}
return errors.Wrap(backup.Finish(), "backup.Finish failed")
})
}
// UpTo runs up to step "up" migrations and applies them to the database.
// If step <= 0 all pending migrations are run.
func (mb *MigrationBox) UpTo(ctx context.Context, step int) (applied int, err error) {
ctx, span := startSpan(ctx, MigrationUpOpName, trace.WithAttributes(attribute.Int("step", step)))
defer otelx.End(span, &err)
c := mb.c.WithContext(ctx)
newDbFileName, isOnDiskSQLite := sqliteFilePath(mb.c.URL())View on GitHub (pinned to 4174065ffb)
Solutions
- Ensure no concurrent writers touch the source or destination during the backup
- Check disk space on the destination volume
- Inspect the wrapped stepErr for the specific SQLite result code
- Retry the restore once the database is quiescent
Example fix
// before backup running while app writes to DB // after mu.Lock() err := restoreSQLiteOnline(ctx, db, srcPath) mu.Unlock()
Defensive patterns
Strategy: retry
Validate before calling
// Ensure destination is idle before restore
if err := db.PingContext(ctx); err != nil { return err }
// Ensure sufficient disk space
if free, _ := diskFree("."); free < minRequiredBytes { return errors.New("insufficient disk space") } Try / catch
for attempt := 0; attempt < 3; attempt++ {
err := restoreSQLiteOnline(ctx, db, srcPath)
if err == nil || !strings.Contains(err.Error(), "backup.Step failed") {
return err
}
time.Sleep(time.Duration(attempt+1) * time.Second)
}
return errors.New("restore failed after retries") Prevention
- Stop application writes during the backup/restore window
- Monitor disk space where the destination DB lives
- Avoid concurrent connections to the destination during restore
- Schedule restores during maintenance windows
When it happens
Trigger: The SQLite backup process fails mid-copy — e.g. the source or destination database is modified/locked during the backup, IO errors occur, or the source file changes underneath the backup handle.
Common situations: Concurrent writes to the source DB during restore; disk full while copying pages; source file truncated or corrupted mid-read; another process holding an exclusive lock.
Related errors
- driver %T does not support online restore
- NewRestore failed
- backup.Finish failed
- failed to write json output
- failed to acquire sql.Conn for restore
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/5dcd4b1fb035eba6.
Report an issue: GitHub.