ory/hydra · error
migrator: problem creating schema migrations
Error message
migrator: problem creating schema migrations
What it means
MigrationBox.exec first ensures the `schema_migrations` tracking table exists via CreateSchemaMigrations before running any migration. If that call fails (DB unreachable, insufficient privileges, dialect issues), the underlying error is wrapped with this message and returned. Callers UpTo and Down abort the whole migration run, so no migrations are applied or rolled back.
Source
Thrown at oryx/popx/migrator.go:684
f, err := os.Create(schema) //#nosec:G304
if err != nil {
return errors.WithStack(err)
}
err = c.Dialect.DumpSchema(f)
if err != nil {
_ = os.RemoveAll(schema)
return errors.WithStack(err)
}
return nil
}
func (mb *MigrationBox) exec(ctx context.Context, fn func() error) error {
now := time.Now()
defer mb.printTimer(now)
err := mb.CreateSchemaMigrations(ctx)
if err != nil {
return errors.Wrap(err, "migrator: problem creating schema migrations")
}
if mb.c.Dialect.Name() == "sqlite3" {
if err := mb.c.RawQuery("PRAGMA foreign_keys=OFF").Exec(); err != nil {
return sqlcon.HandleError(err)
}
}
switch mb.c.Dialect.Name() {
case dbal.DriverCockroachDB, dbal.DriverYugabyteDB:
outer := fn
fn = func() error {
// CreateSchemaMigrations runs before this wrapper. YugabyteDB uses
// autocommit DDL, but its pgwire errors expose the same retryable
// SQLSTATEs that crdb.Execute classifies for whole-run retries.
return errors.WithStack(crdb.Execute(outer))
}
}View on GitHub (pinned to 4174065ffb)
Solutions
- Verify the database is reachable and the DSN in the connection details/environment is correct (try a plain query with the same credentials).
- Grant the migration user CREATE privileges (e.g. GRANT CREATE ON DATABASE ...) or run migrations as a DDL-capable role.
- Inspect the wrapped cause: drop/recreate a corrupt schema_migrations table only if its contents can be reconstructed from applied migration timestamps.
- Confirm driver/dialect match (e.g. using the sqlite3 dialect on a file path that exists and is writable).
Example fix
// before (app role without DDL rights) DATABASE_URL=postgres://app_reader:...@db:5432/mydb?sslmode=disable // after DATABASE_URL=postgres://app_migrator:...@db:5432/mydb?sslmode=disable -- with: GRANT CREATE ON DATABASE mydb TO app_migrator;
Defensive patterns
Strategy: try-catch
Validate before calling
// before running migrations
if err := db.RawQuery("SELECT 1").Exec(); err != nil {
return fmt.Errorf("database unreachable, aborting migrations: %w", err)
}
// check DDL rights
canCreate, err := canCreateTables(db) // e.g. SELECT has_database_privilege(current_user, current_database(), 'CREATE') Try / catch
if err := migrator.UpTo(ctx, steps...); err != nil {
if strings.Contains(err.Error(), "problem creating schema migrations") {
// inspect cause: connectivity / privileges / corrupt schema_migrations
log.Printf("schema_migrations setup failed: %+v", err)
return fmt.Errorf("migration bootstrap failed: %w", errors.Unwrap(err))
}
return err
} Prevention
- Run migrations as a dedicated role with CREATE privileges, separate from the runtime app role.
- Add a startup health check (SELECT 1) before invoking migrations in CI and deploy scripts.
- Keep pop versions consistent between environments to avoid schema_migrations format drift.
- Monitor DB availability (container status, connection limits) before deploy pipelines trigger migrations.
When it happens
Trigger: Calling UpTo(ctx, mb, ...) or Down(ctx, mb, ...) when mb.CreateSchemaMigrations returns an error: database is down/unreachable, the DB user lacks CREATE TABLE privileges, the schema_migrations table exists in a corrupt/incompatible form, or the driver/dialect fails on the CREATE TABLE IF NOT EXISTS statement.
Common situations: Database container not started or wrong DSN/host in config before running `pop migrate`; CI pipelines pointing at a migrations-restricted user; production DBs where the app role lacks DDL rights; stale/corrupt schema_migrations left by an interrupted earlier migration with a different pop version.
Related errors
- migrations have not yet been fully applied: %+v
- 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
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/16fe48caedaec046.
Report an issue: GitHub.