How to Fix Prisma "Migration Failed to Apply" Errors
A Prisma migration failing to apply means the SQL Prisma generated from your schema changes couldn't run successfully against the actual database — and because migrations often run as a sequence, a single failed migration can leave the database in a partially-applied state that blocks subsequent migrations too, which is why this error tends to compound if not addressed directly.
The most common direct cause is a migration that conflicts with existing data — adding a non-nullable column to a table that already has rows, for instance, fails outright unless a default value is provided, since the database has no value to put in that new column for existing records. Prisma's migration generation usually warns about this at generation time if you're prompted interactively, but a migration created without that prompt (in a CI environment, for example) can fail at apply-time instead.
Schema drift — the actual database structure no longer matching what Prisma's migration history believes it should be — is another frequent cause, often introduced by someone making a manual change directly in the database (a quick fix applied through a database GUI, bypassing Prisma entirely) that Prisma's migration history has no record of. The next migration Prisma tries to apply assumes a starting state that doesn't actually match reality, and fails.
Prisma's `migrate status` command is the right first step for any failed migration — it shows exactly which migrations have been applied, which are pending, and specifically flags any migration that failed partway through, which is essential information before deciding how to proceed, since blindly retrying a migration that's already partially applied can make the situation worse rather than better.
For a migration that failed partway through applying its SQL, Prisma provides `migrate resolve` specifically for marking a migration as either rolled back (if you've manually reverted whatever partial changes it made) or applied (if you've manually completed what it was trying to do) — this reconciles Prisma's migration history with the database's actual state, which is necessary before any further migrations can run cleanly.
In a development environment where the actual data doesn't matter, `migrate reset` is the blunt but effective fix — it drops the database, recreates it, and reapplies all migrations from scratch, sidestepping any drift or partial-application issues entirely. This should never be used against a production database with real data, since it's explicitly destructive by design.
For production databases specifically, the safer path is diagnosing exactly what the failed migration's SQL was trying to do, manually applying the equivalent change with appropriate data handling (backfilling a default value for a new non-nullable column, for instance), and then using `migrate resolve --applied` to tell Prisma that migration is now correctly reflected in the database — more careful than a reset, but necessary when the data actually matters.
Found this helpful?
SyncTonight's tools and guides are free and always will be. If this post saved you some debugging time, a coffee goes a long way — no pressure, just appreciated.
☕ Buy me a coffee