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.
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.
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
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.
P1013: The provided database string is invalid
The provided database string is invalid
P1000: Authentication failed against database server
Authentication failed against database server
P1010: User was denied access on the database
How to fix "P1010: User was denied access on the database" in Prisma
P5008: Usage exceeded, upgrade your plan (Accelerate)
How to fix "Usage exceeded, upgrade your plan" in Prisma Accelerate
P3021: Foreign keys cannot be created on this database
How to fix 'P3021: Foreign keys cannot be created on this database' in Prisma