ory/hydra · error

migration down: unable count existing migration

Error message

migration down: unable count existing migration

What it means

Before running Down migrations, the migrator counts rows in the schema_migration table to determine how many steps can be reverted. This error wraps a failure of that COUNT query against the migrations table. It means the tracking table could not be read at all.

Source

Thrown at oryx/popx/migrator.go:345

// Down runs pending "down" migrations and rolls back the
// database by the specified number of steps.
// If step <= 0, all down migrations are run.
func (mb *MigrationBox) Down(ctx context.Context, steps int) (err error) {
	ctx, span := startSpan(ctx, MigrationDownOpName, trace.WithAttributes(attribute.Int("steps", steps)))
	defer otelx.End(span, &err)

	if steps <= 0 {
		steps = math.MaxInt
	}
	remainingSteps := steps

	c := mb.c.WithContext(ctx)
	return errors.WithStack(mb.exec(ctx, func() (err error) {
		mtn := sanitizedMigrationTableName(c)
		count, err := c.Count(mtn)
		if err != nil {
			return errors.Wrap(err, "migration down: unable count existing migration")
		}
		attemptSteps := min(remainingSteps, count)

		mfs := mb.migrationsDown.sortAndFilter(mb.c.Dialect.Name(), mb.migrationFallbacks()...)
		slices.Reverse(mfs)
		if len(mfs) > count {
			// skip all migrations that were not yet applied
			mfs = mfs[len(mfs)-count:]
		}

		reverted := 0
		defer func() {
			migrationsToRevertCount := min(attemptSteps, len(mfs))
			mb.l.Debugf("Successfully reverted %d/%d migrations.", reverted, migrationsToRevertCount)
			if err != nil {
				mb.l.WithError(err).Error("Problem reverting migrations.")
			}
		}()

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Confirm you are connected to the correct database (check DSN)
  2. Verify the schema_migration table exists; run migrations init/up first if the database was never migrated
  3. Check the wrapped cause for the underlying SQL error and address privileges or connectivity
Defensive patterns

Strategy: validation

Validate before calling

var n int
if err := db.QueryRow("SELECT COUNT(*) FROM schema_migration").Scan(&n); err != nil {
    return fmt.Errorf("schema_migration table not readable; run migrations init/up first: %w", err)
}

Try / catch

if err := box.Down(ctx, 1); err != nil {
    if strings.Contains(err.Error(), "unable count existing migration") {
        // verify DSN and that the DB has been migrated before attempting rollback
    }
    return err
}

Prevention

When it happens

Trigger: Calling MigrationBox.Down when the schema_migration table does not exist (migrations never initialized), is corrupted, or the query fails due to permissions/connection issues.

Common situations: Running Down on a fresh database that never had migrations applied; wrong DSN pointing to an empty database; table renamed manually; revoked SELECT privileges.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/2cd79d74e02fae4b. Report an issue: GitHub.