Common Prisma errors with Supabase

Fixes for P1001, P1000, P1003, shadow database P3014, prepared statement errors and baselining when using Prisma with a Supabase project on SupaHost over the SSH tunnel.

Prisma talks to Postgres directly, not through the Data API. On SupaHost that means the SSH tunnel, which is available on the Business and Enterprise plans. On other plans, use supabase-js (or another Data API client) from your app instead; see Can I use Drizzle or Prisma without supabase-js?.

The connection string

  1. Add your SSH public key: Dashboard → your project → Connect tab → SSH & CLI → Add key. Keys apply to the whole instance.
  2. Open the tunnel and leave it running:
ssh -N -L 5432:127.0.0.1:5432 [email protected]
  1. Copy the string from Dashboard → your project → Connect tab → Database → Show connection string into .env:
DATABASE_URL="postgresql://postgres:[email protected]:5432/p_app_one?connection_limit=5"

Point Prisma at DATABASE_URL wherever your version reads it: url = env("DATABASE_URL") in schema.prisma up to Prisma 6, or prisma.config.ts in Prisma 7. There's no pooler, so you don't need a separate directUrl.

P1001: Can't reach database server

Error: P1001: Can't reach database server at `127.0.0.1:5432`
  • The tunnel isn't running, or it dropped. Start it again (step 2).
  • You used the project hostname, such as app-one.acme.supahost.space:5432. Postgres isn't exposed on the internet; it only listens on the instance itself. Always connect to 127.0.0.1 through the tunnel.
  • A local Postgres already uses port 5432. Forward to another local port (-L 15432:127.0.0.1:5432) and use 127.0.0.1:15432 in the URL.

P1000: Authentication failed

Error: P1000: Authentication failed against database server, the provided database credentials for `postgres` are not valid.

Copy the password again from Show connection string. If it contains characters like @, # or /, URL-encode them. See FATAL: password authentication failed.

P1003: Database does not exist, or no tables

Error: P1003: Database `app_one` does not exist on the database server

Each SupaHost project is its own database named p_ plus the project name with dashes turned into underscores. Project app-one is p_app_one.

If your URL ends in /postgres, Prisma connects without an error but to the wrong database: postgres is a system database on the instance, not your project. prisma db pull finds nothing and prisma migrate deploy would create your tables there. Use the string from Show connection string, which already has the right name.

P3014: Prisma Migrate could not create the shadow database

Error: P3014: Prisma Migrate could not create the shadow database.

prisma migrate dev creates and drops a temporary database to check your migrations. Don't do that against your SupaHost project. Instead:

  • Run prisma migrate dev against a local Postgres (the Supabase CLI's local stack works well), and commit the generated migrations.
  • Apply them to SupaHost with prisma migrate deploy, which doesn't need a shadow database.

prepared statement "s0" already exists

You'll only see this with a transaction-mode pooler such as PgBouncer or Supavisor in port 6543 mode. SupaHost has no pooler: you connect straight to Postgres, so remove pgbouncer=true from URLs copied from other setups. See prepared statement "s0" already exists.

P3005: The database schema is not empty

Your project already has tables (made in Studio, or imported). Baseline once so Prisma treats the current schema as its starting point:

mkdir -p prisma/migrations/0_init
npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
npx prisma migrate resolve --applied 0_init

In Prisma 7 the --to-schema-datamodel flag is called --to-schema.

Prisma wants to touch auth or storage tables

Keep Prisma on the public schema. Tables in auth, storage and the other Supabase schemas are managed by Auth and Storage, and Prisma migrations that alter them can break sign-in or uploads. To relate rows to users, store the user id as a uuid column and add the foreign key to auth.users in a SQL migration.

Too many connections

All projects on an instance share one Postgres server with 400 connections. Each Prisma client opens a pool, so keep connection_limit small, and reuse one PrismaClient per process. If you use a driver adapter such as @prisma/adapter-pg (the default setup in Prisma 7), set the pool size on the adapter instead (max: 5). See Too many connections.

Watch out: RLS doesn't apply

Prisma connects as postgres, which bypasses RLS in Supabase's Postgres image, so your policies don't filter its queries. Do authorization checks in your server code for every query.

Updated 11 November 2026 · View as Markdown · Something wrong or missing? Tell us