ory/hydra · error
problem deleting migration version %s
Error message
problem deleting migration version %s
What it means
During a transactional Down migration, the rollback and the DELETE of the version row share one transaction; if the DELETE fails the whole transaction (including the rollback) is undone and this error is returned. The database remains consistent — the migration was simply not reverted.
Source
Thrown at oryx/popx/migrator.go:412
err := mi.Runner(mi, c)
if err != nil {
return errors.WithStack(err)
}
// #nosec G201 - mtn is a system-wide const
if err := c.RawQuery(fmt.Sprintf("DELETE FROM %s WHERE version = ?", mtn), mi.Version).Exec(); err != nil {
return errors.Wrapf(err, "problem deleting migration version %s. YOUR DATABASE MAY BE IN AN INCONSISTENT STATE! MANUAL INTERVENTION REQUIRED!", mi.Version)
}
} else {
if err := mb.isolatedTransaction(ctx, "down", func(conn *pop.Connection) error {
err := mi.Runner(mi, conn)
if err != nil {
return errors.WithStack(err)
}
// #nosec G201 - mtn is a system-wide const
if err := conn.RawQuery(fmt.Sprintf("DELETE FROM %s WHERE version = ?", mtn), mi.Version).Exec(); err != nil {
return errors.Wrapf(err, "problem deleting migration version %s", mi.Version)
}
return nil
}); err != nil {
return errors.WithStack(err)
}
}
l.Infof("%s applied successfully", mi.Name)
reverted++
remainingSteps--
}
return nil
}))
}
func (mb *MigrationBox) createTransactionalMigrationTable(ctx context.Context, c *pop.Connection, l *logrusx.Logger) error {
mtn := sanitizedMigrationTableName(c)View on GitHub (pinned to 4174065ffb)
Solutions
- Inspect the wrapped cause for the underlying SQL error and fix it
- Confirm schema_migration exists and the DB user has DELETE privileges
- Re-run Down after the fix; transactional semantics guarantee no partial state
Defensive patterns
Strategy: try-catch
Validate before calling
var n int
if err := db.QueryRow("SELECT COUNT(*) FROM schema_migration").Scan(&n); err != nil {
return fmt.Errorf("tracking table unreadable before Down: %w", err)
} Try / catch
if err := box.Down(ctx, 1); err != nil {
if isTransient(err) {
time.Sleep(time.Second)
return box.Down(ctx, 1) // transactional: safe to retry, state is consistent
}
return err
} Prevention
- Keep stable connectivity during rollback runs
- Grant DELETE privileges on schema_migration
- Do not lock or drop the tracking table while migrations run
When it happens
Trigger: Calling Down for a transactional migration where DELETE FROM schema_migration fails inside the isolated transaction: unique/foreign-key issues, table missing, privileges, or connection loss mid-transaction.
Common situations: schema_migration dropped or locked by another process; revoked DELETE privileges; transient connection failures during long rollbacks.
Related errors
- problem inserting migration version %s
- problem inserting migration version %s. YOUR DATABASE MAY BE
- migration down: unable count existing migration
- problem checking for legacy migration version %s
- neither normal (%s) nor legacy migration (%s) exist
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/dfe8e5cfe9f28d53.
Report an issue: GitHub.