# 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.

Source: https://supahost.app/kb/prisma-errors · Updated 2026-11-11

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?](/kb/orm-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:

```bash
ssh -N -L 5432:127.0.0.1:5432 supahost@acme.supahost.space
```

3. Copy the string from *Dashboard → your project → **Connect** tab → Database → Show connection string* into `.env`:

```bash
DATABASE_URL="postgresql://postgres:YOUR_PASSWORD@127.0.0.1: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](/kb/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](/kb/prepared-statement-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:

```bash
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](/kb/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.

## Related

- [Prisma](/docs/integrations/prisma)
- [SSH access and direct Postgres](/docs/platform/ssh)
- [Connecting directly to Postgres (psql, pg_dump, ORMs)](/kb/direct-postgres-connection)
- [Connection refused or timeout when connecting to Postgres](/kb/connection-refused)
