How to fix P3012: Migration {migration_name} cannot be rolled back because it is not in a failed state. in Prisma
This error occurs when attempting to mark a migration as rolled back using `prisma migrate resolve --rolled-back`, but the migration is not currently in a failed state. The rollback flag only works with migrations that have actually failed during application.
Quick fix
Fixes P3012
npx prisma migrate status- Check the current migration status
- For successfully applied migrations: Create a new forward migration
- For truly failed migrations: Use --rolled-back correctly
- Development only: Reset database and migrations
npx prisma migrate statusP3012: Migration {migration_name} cannot be rolled back because it is not in a failed state.
npx prisma migrate statusWhat this error means
The P3012 error indicates that you're trying to use the `prisma migrate resolve --rolled-back` command on a migration that is not marked as failed in Prisma's migration history. This is a deliberate constraint in Prisma Migrate's design. The `--rolled-back` flag is specifically designed to mark failed migrations as rolled back so they can be reapplied. If a migration has successfully applied, or was never applied at all, it cannot be marked as rolled back because it's not in a failed state. This limitation exists to maintain migration history integrity and prevent users from accidentally corrupting their migration state by rolling back successfully applied migrations without proper safeguards.
Typical symptoms
- Error message "P3012: Migration cannot be rolled back because it is not in a failed state" when running migrate resolve
- Unable to mark a migration as rolled back even after manually reverting database changes
- Command `npx prisma migrate resolve --rolled-back <migration>` fails with P3012
- Migration shows as applied in _prisma_migrations table but you want to revert it
Common causes
- Attempting to use --rolled-back on a migration that successfully applied to the database
- Trying to roll back a migration that was previously marked as applied using --applied flag
- Confusing the --rolled-back flag with a general undo mechanism for any migration
- Following down migration workflow but migration state is not marked as failed
- Using --rolled-back on a migration that was never applied (shows as not applied, not failed)
How to fix "P3012: Migration {migration_name} cannot be rolled back because it is not in a failed state."
First, verify the state of your migrations in the database:
npx prisma migrate statusLook for the migration in question and note its status. The --rolled-back flag only works with migrations showing a "failed" status.
You can also directly query the migration history table:
SELECT migration_name, finished_at, rolled_back_at, applied_steps_count
FROM _prisma_migrations
ORDER BY finished_at DESC;If the migration shows as successfully applied (has a finished_at timestamp and no errors), you cannot use --rolled-back.
If the migration was successfully applied but you need to undo its changes, create a new migration that reverses the changes:
# Make changes to your schema.prisma to undo the unwanted changes
# Then create a new migration
npx prisma migrate dev --name revert_previous_changesThis is the recommended approach for production databases. Never manually modify successfully applied migrations.
Alternatively, for development environments, you can use prisma migrate diff to generate a down migration:
# Generate SQL to revert changes
npx prisma migrate diff \
--from-schema-datamodel prisma/schema.prisma \
--to-schema-datasource prisma/schema.prisma \
--script > down.sqlIf you have a migration that genuinely failed during application (showing failed status), first manually roll back any partial changes it made to the database, then mark it as rolled back:
# Manually revert any partial database changes from the failed migration
# Then mark it as rolled back
npx prisma migrate resolve --rolled-back "20231215_migration_name"After marking as rolled back, you can fix the migration file and reapply:
npx prisma migrate deployFor local development databases where data loss is acceptable:
# Reset database and reapply all migrations from scratch
npx prisma migrate resetThis will:
1. Drop the database
2. Create a new database
3. Apply all migrations from the migrations folder
4. Run seed scripts if configured
Warning: This deletes all data. Never use this in production or staging environments.
If you previously used --applied to mark a migration that shouldn't have been marked as applied:
# Manually update the _prisma_migrations table to remove the migration record
# Then you can reapply it properlyDirect SQL approach (use with caution):
DELETE FROM _prisma_migrations
WHERE migration_name = '20231215_migration_name';Then run:
npx prisma migrate deployThis approach should only be used when you're certain the migration was never actually applied to the database despite being marked as such.
Advanced notes
Understanding Migration States:
Prisma tracks migrations in the _prisma_migrations table with these key states:
- Applied: Migration ran successfully (finished_at is set, rolled_back_at is null)
- Failed: Migration started but encountered an error (started_at is set, finished_at is null or has error details)
- Rolled back: Previously failed migration that was manually reverted (rolled_back_at is set)
Why This Limitation Exists:
The restriction on --rolled-back is intentional. Prisma Migrate doesn't provide automatic rollback functionality for successfully applied migrations because:
1. Database schema changes are often not safely reversible (data may be lost)
2. In production, you should always move forward with new migrations
3. It prevents accidental corruption of migration history
Alternative Workflows:
For development, consider using prisma db push instead of migrations when rapidly iterating on schema design. It doesn't create migration files and directly syncs your schema to the database.
For production hotfixes, follow Prisma's [patching and hotfixing workflow](https://www.prisma.io/docs/orm/prisma-migrate/workflows/patching-and-hotfixing) which involves creating forward migrations to fix issues.
Common Confusion:
Many developers expect --rolled-back to work like a git revert, but it's specifically for marking failed migrations as manually reverted so they can be fixed and reapplied. For successfully applied migrations you want to undo, you must create a new forward migration that reverses the changes.
Frequently asked questions
- What does "P3012" mean?
- The P3012 error indicates that you're trying to use the prisma migrate resolve --rolled-back command on a migration that is not marked as failed in Prisma's migration history. This is a deliberate constraint in Prisma Migrate's design. The --rolled-back flag is specifically designed to mark failed migrations as rolled back so they can be reapplied.
- How do I fix "P3012"?
- This error occurs when attempting to mark a migration as rolled back using prisma migrate resolve --rolled-back, but the migration is not currently in a failed state. The rollback flag only works with migrations that have actually failed during application.
- What causes "P3012"?
- Attempting to use --rolled-back on a migration that successfully applied to the database Trying to roll back a migration that was previously marked as applied using --applied flag Confusing the --rolled-back flag with a general undo mechanism for any migration
- Is the "P3012" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Prisma Official Documentation
- ๐prisma.io - error reference(Official Docs)
- ๐prisma.io - troubleshooting(Official Docs)
- ๐prisma.io - production troubleshooting(Official Docs)
- ๐prisma.io - patching and hotfixing(Official Docs)
- ๐github.com - 3420(GitHub)
- ๐github.com - 14286(GitHub)
- ๐prisma.io - prisma migrate dx primitives(Official Docs)
- ๐prisma.io - generating down migrations(Official Docs)