How to fix P3004: The database is a system database and should not be altered in Prisma
The Prisma P3004 error occurs when attempting to run migrations against a reserved system database like "mysql", "postgres", or "information_schema". This prevents accidental corruption of critical database infrastructure. The fix requires connecting to a user-created application database instead.
Quick fix
Fixes P3004
# BAD - Points to MySQL system database
DATABASE_URL="mysql://user:password@localhost:3306/mysql"
# BAD - Points to PostgreSQL system database
DATABASE_URL="postgresql://user:password@localhost:5432/postgres"
# GOOD - Points to custom application database
DATABASE_URL="mysql://user:password@localhost:3306/myapp_db"
DATABASE_URL="postgresql://user:password@localhost:5432/myapp_production"- Identify the system database in your connection string
- Create a new application database
- Update your DATABASE_URL connection string
- Verify the connection to your new database
# BAD - Points to MySQL system databaseDATABASE_URL="mysql://user:password@localhost:3306/mysql"# BAD - Points to PostgreSQL system databaseDATABASE_URL="postgresql://user:password@localhost:5432/postgres"# GOOD - Points to custom application databaseDATABASE_URL="mysql://user:password@localhost:3306/myapp_db"DATABASE_URL="postgresql://user:password@localhost:5432/myapp_production"P3004: The database is a system database and should not be altered
What this error means
The P3004 error in Prisma Migrate is a safety mechanism that prevents you from running migrations against system databases that are essential for the database server's operation. When you attempt to run commands like `prisma migrate dev` or `prisma db push` against a system database, Prisma will refuse to continue with the message: "The {database_name} database is a system database, it should not be altered with prisma migrate. Please connect to another database." This error most commonly occurs with MySQL databases, where the default system database is named "mysql". Database servers like MySQL, PostgreSQL, and SQL Server maintain internal system databases that store metadata, user accounts, permissions, and other critical infrastructure information. These databases include: - MySQL: `mysql`, `information_schema`, `performance_schema`, `sys` - PostgreSQL: `postgres`, `template0`, `template1` - SQL Server: `master`, `model`, `msdb`, `tempdb` The error is particularly common for newcomers to Prisma who may not realize that a database server hosts multiple databases, and that some database names are reserved for system use. Attempting to use these system databases for application data can corrupt the database server and cause catastrophic failures. Prisma detects system database names and blocks migration operations as a protective measure. This is a deliberate design choice to prevent accidental data loss and maintain database server integrity.
Typical symptoms
- Prisma migrate dev fails immediately with P3004 error
- Error message specifically mentions a system database name like "mysql" or "postgres"
- Prisma db push commands are rejected with system database warnings
- Migration commands work in development but fail in production when pointing to system databases
- New Prisma projects fail to initialize migrations when DATABASE_URL contains a system database
Common causes
- DATABASE_URL environment variable points to a system database like "mysql" or "postgres"
- Connection string uses the default database name instead of a custom application database
- Copying connection string templates without changing the database name
- Misunderstanding that database servers contain multiple databases
- Using database server default connection URLs that point to system databases
- Cloud database providers giving default connection strings that include system database names
How to fix "P3004: The database is a system database and should not be altered"
Check your DATABASE_URL in your .env file or environment variables. Look for system database names in the connection string:
# BAD - Points to MySQL system database
DATABASE_URL="mysql://user:password@localhost:3306/mysql"
# BAD - Points to PostgreSQL system database
DATABASE_URL="postgresql://user:password@localhost:5432/postgres"
# GOOD - Points to custom application database
DATABASE_URL="mysql://user:password@localhost:3306/myapp_db"
DATABASE_URL="postgresql://user:password@localhost:5432/myapp_production"The database name is the last segment of the connection URL after the port number.
Connect to your database server and create a dedicated database for your application:
MySQL:
CREATE DATABASE myapp_db;
-- Grant permissions
GRANT ALL PRIVILEGES ON myapp_db.* TO 'your_user'@'localhost';
FLUSH PRIVILEGES;PostgreSQL:
CREATE DATABASE myapp_db;
-- Grant permissions
GRANT ALL PRIVILEGES ON DATABASE myapp_db TO your_user;SQL Server:
CREATE DATABASE myapp_db;Choose a descriptive name that identifies your application and environment (e.g., ecommerce_dev, blog_production).
Modify your .env file to point to the newly created database:
# Before
DATABASE_URL="mysql://user:password@localhost:3306/mysql"
# After
DATABASE_URL="mysql://user:password@localhost:3306/myapp_db"Make sure to update all environment files:
- .env (local development)
- .env.production (production settings)
- Environment variables in your deployment platform (Vercel, Railway, Heroku, etc.)
If you have multiple environments (development, staging, production), ensure each has its own dedicated database.
Test the database connection before running migrations:
# Prisma will validate the connection
npx prisma db pullOr connect manually:
# MySQL
mysql -u your_user -p -h localhost myapp_db
# PostgreSQL
psql postgresql://user:password@localhost:5432/myapp_dbIf the connection fails, verify:
- Database name is spelled correctly
- Database exists on the server
- User has proper permissions
- Connection string format is correct
Now that you're connected to a user database, initialize or apply your migrations:
# Development - creates migrations and applies them
npx prisma migrate dev
# Production - applies existing migrations
npx prisma migrate deploy
# Generate Prisma Client
npx prisma generateThis will create the _prisma_migrations table and all your schema tables in the new application database, leaving system databases untouched.
Prevent this issue from recurring:
1. Update .env.example with the correct database name pattern:
DATABASE_URL="mysql://user:password@localhost:3306/your_app_name"2. Document the setup process in your README:
"Create a dedicated database for this application. Do not use system databases like 'mysql' or 'postgres'."
3. Configure CI/CD to use test databases with proper names
4. Share environment configuration with team members to ensure consistency
Advanced notes
Why This Protection Exists: System databases store critical metadata including user accounts, privileges, stored procedures, and database server configuration. Running Prisma migrations against these databases could:
- Drop critical system tables
- Corrupt authentication mechanisms
- Break other applications sharing the same database server
- Make the entire database server unusable
Cloud Database Considerations: Some managed database providers (like PlanetScale, Railway, or Supabase) automatically create dedicated databases and never expose system databases in connection strings. However, traditional database servers (self-hosted MySQL, PostgreSQL on AWS RDS, Azure Database) require manual database creation.
Database vs Schema: In PostgreSQL, there's a distinction between databases and schemas. While Prisma blocks system databases, you can create multiple schemas within a single database. The P3004 error only applies to database-level protection, not schema-level.
Connection String URL Encoding: If your application database name contains special characters, ensure they're properly URL-encoded in the connection string:
# Special characters need encoding
DATABASE_URL="mysql://user:password@localhost:3306/my%2Bapp%23db"Multiple Applications on One Server: If you're running multiple applications on the same database server, each application should have its own dedicated database. Don't try to use system databases as a workaround for multi-tenancy.
Migration History: If you accidentally ran migrations against a system database before Prisma added this protection (pre-2.15.0), you may have a _prisma_migrations table in a system database. You can safely drop this table manually, but do not attempt to run prisma migrate to clean it up.
Frequently asked questions
- What does "P3004" mean?
- The P3004 error in Prisma Migrate is a safety mechanism that prevents you from running migrations against system databases that are essential for the database server's operation. When you attempt to run commands like prisma migrate dev or prisma db push against a system database, Prisma will refuse to continue with the message: "The {database_name} database is a system database, it should not be altered with prisma migrate. " This error most commonly occurs with MySQL databases, where the default system database is named "mysql".
- How do I fix "P3004"?
- The Prisma P3004 error occurs when attempting to run migrations against a reserved system database like "mysql", "postgres", or "information_schema". This prevents accidental corruption of critical database infrastructure. The fix requires connecting to a user-created application database instead.
- What causes "P3004"?
- DATABASE_URL environment variable points to a system database like "mysql" or "postgres" Connection string uses the default database name instead of a custom application database Copying connection string templates without changing the database name
- Is the "P3004" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Prisma Official Documentation
- ๐prisma.io - error reference(Official Docs)
- ๐github.com - 4682(GitHub)
- ๐prisma.io - troubleshooting(Official Docs)
- ๐
- ๐prisma.io - getting started(Official Docs)
- ๐
- ๐supabase.com - prisma troubleshooting(Official Docs)