DEV Community

Cover image for Prisma Migrate P3014: permission denied to create database
Mahdi BEN RHOUMA
Mahdi BEN RHOUMA

Posted on Originally published at iloveblogs.blog

Prisma Migrate P3014: permission denied to create database

The P3014 error: permission denied to create database

A developer on Stack Overflow reported running npx prisma migrate dev --name init --preview-feature against a Heroku‑hosted PostgreSQL database and hitting this exact output:

P3014

Prisma Migrate could not create the shadow database. Please make sure the database user has permission to create databases.  More info: https://pris.ly/d/migrate-shadow. Original error:
Database error: Error querying the database: db error: ERROR: permission denied to create database
Enter fullscreen mode Exit fullscreen mode

The error fires every time you attempt a migration on a managed PostgreSQL service that does not grant the CREATEDB privilege. The three workable fixes are: switch to prisma db push, provision a separate shadow database on Heroku, or, for self‑managed databases, grant the CREATEDB privilege directly.

Why Heroku Postgres can’t create shadow databases

prisma migrate dev needs a temporary shadow database to perform a dry‑run of the migration against a clean schema. It creates this shadow database with a name like prisma_migrate_shadow_db_<hash>, executes the migration inside it, and drops it afterward. The creation step requires the connected database user to hold the CREATEDB attribute.

Managed PostgreSQL offerings — Heroku Postgres, Supabase Postgres, AWS RDS with restricted accounts — do not grant CREATEDB to the default database user. The user you get from the Heroku dashboard has only the privileges needed to operate inside the single database your application uses. When prisma migrate dev tries to CREATE DATABASE inside that instance, PostgreSQL returns “permission denied to create database”, and Prisma surfaces it as error P3014.

This is not a bug in Prisma; it’s a deliberate security restriction on the database host. If you are working with a local PostgreSQL installation or a VPS where you control the roles, the user can be given CREATEDB and the error disappears. On Heroku you must take a different path.

Three ways to fix the P3014 error

Fix 1: Use prisma db push to skip the shadow database entirely

prisma db push synchronises your Prisma schema with the database without creating a migration history or a shadow database. It is the fastest way to get tables onto Heroku Postgres when you are prototyping or when you do not need a tracked migration record.

npx prisma db push
Enter fullscreen mode Exit fullscreen mode

After the command finishes you’ll see output listing the tables and columns that were created, similar to:

✔ Generated Prisma Client (4.x.x) to ./node_modules/@prisma/client in 45ms
The database is already in sync with the current schema.
Enter fullscreen mode Exit fullscreen mode

For most Heroku free‑tier projects, prisma db push is sufficient. It keeps your schema in sync and you can generate the Prisma Client afterwards with npx prisma generate.

Fix 2: Create a shadow database on Heroku and set shadowDatabaseUrl

If you need the migration history that prisma migrate dev provides (generating migration files under prisma/migrations), you can give Prisma a separate database to use as its shadow. On Heroku, provision a second Postgres add‑on — even the free Hobby‑dev plan works — and use that connection string exclusively for the shadow.

Once the second database is ready, add its connection string to your .env file:

DATABASE_URL="postgres://user:pass@ec2-xx-xx-xx-xx.compute-1.amazonaws.com:5432/dbname"
SHADOW_DATABASE_URL="postgres://user:pass@ec2-yy-yy-yy-yy.compute-1.amazonaws.com:5432/dbname"
Enter fullscreen mode Exit fullscreen mode

Then reference it in the datasource block of your schema.prisma:

datasource db {
  provider          = "postgresql"
  url               = env("DATABASE_URL")
  shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}
Enter fullscreen mode Exit fullscreen mode

Now run npx prisma migrate dev --name init. Prisma will create the shadow tables inside the second database instead of trying to create an entirely new database, so the CREATEDB permission is no longer required.

Keep the shadow database credentials out of public version control. The shadow database itself should contain no production data; Prisma cleans it up automatically after each migration, so you can reuse the same second instance indefinitely.

Fix 3: Grant CREATEDB to a PostgreSQL user (for self‑managed databases)

If you are not on a managed service — for example, you are connecting to a local PostgreSQL instance or a VPS where you have superuser access — you can grant the necessary privilege directly:

ALTER USER your_db_user CREATEDB;
Enter fullscreen mode Exit fullscreen mode

Replace your_db_user with the actual role name Prisma connects with. After this change, prisma migrate dev will be able to create and drop the shadow database on the same server.

This approach will not work on Heroku Postgres or any managed offering that restricts role attributes. Attempting ALTER ROLE on Heroku will return a different permission error. In those environments choose Fix 1 or Fix 2.

Verify the fix

For Fix 1, run npx prisma db push and confirm the output shows “The database is already in sync” or lists the new tables created.

For Fix 2, run npx prisma migrate dev --name init and watch for lines like:

Applying migration `20260925000000_init`
The following migration(s) have been applied:
migrations/
  └─ 20260925000000_init/
    └─ migration.sql
Your database is now in sync with your schema.
Enter fullscreen mode Exit fullscreen mode

No P3014 error should appear, and the shadow DB operations will reference the second connection string.

For Fix 3, after granting CREATEDB, run prisma migrate dev and see the migration complete without the permission error.

Other Prisma migration errors you might run into

prisma migrate dev hangs indefinitely

If you are using a Supabase database, the default connection string Supabase provides uses port 6543 (the PgBouncer pooler in transaction mode). Prisma Migrate does not work correctly through a transaction‑mode pooler — it will print the datasource line and then hang with no further output.

Fix: Switch to the direct session‑mode connection on port 5432. You can find it in the Supabase dashboard under Project Settings → Database → Connection pool → Connection string (Session mode). Use that connection string as DATABASE_URL when running prisma migrate dev.

If you encounter a hang, check the port first. The Prisma Can't Connect to PostgreSQL: Fix invalid port guide details how a wrong port produces misleading errors, and Prisma: Environment variable not found: DATABASE_URL helps if your connection string is not loaded at all.

TLS UnsupportedCertVersion error

In some Deno‑based setups (Deno Deploy, local Deno with denodb (PostgresConnector)), you may see:

TLS connection failed with message: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
Defaulting to non-encrypted connection
Enter fullscreen mode Exit fullscreen mode

This happens when TLS certificate validation fails because the Deno runtime does not trust the certificate used by your PostgreSQL provider. The connection may still succeed over a non‑encrypted fallback, but that removes transport security.

A temporary workaround is to run Deno with the --unsafely-ignore-certificate-errors flag:

deno run --unsafely-ignore-certificate-errors your_script.ts
Enter fullscreen mode Exit fullscreen mode

This is not safe for production — it should only be used for local debugging or when you control the network completely. The proper fix is to update the Deno runtime or configure a custom CA certificate bundle that trusts the database server’s certificate.

FAQ

Can I use prisma db push in production?

Yes, prisma db push works in production, but it does not generate migration files. This means you lose a traceable history of schema changes. For small teams and side‑projects it is often acceptable; for larger applications, prefer prisma migrate dev with a properly configured shadow database.

Does Heroku’s free tier allow creating a shadow database?

Yes. You can add a second Hobby‑dev Postgres database to your Heroku app. Use its connection string for SHADOW_DATABASE_URL. The free tier includes row and storage limits, but the shadow database only holds temporary tables during migrations and is dropped automatically, so its usage stays well within those limits.

Related


Originally published at https://www.iloveblogs.blog

Top comments (0)