The error, verbatim
Jump to the fix ↓Error: P1001: Can't reach database server at `localhost:5432`
Please make sure your database server is running at `localhost:5432`.
Tested on
- prisma
- 6.19.3 and 7.10.0
- Postgres
- 17 (Docker), Supabase CLI 2.120.0 local
- Docker
- Desktop 4.94.0, node:24-alpine
- Node / OS
- 24.14.0 / Windows 11 Pro
Contents
P1001 means Prisma opened no connection at all. It never got as far as your password or your database name. The trouble is that it prints exactly the same sentence whatever the reason. I triggered it five different ways, and the message only ever changed in the host and port:
| What was wrong | What Prisma 6 said |
|---|---|
| Nothing listening on that port (database stopped, or wrong port) | P1001: Can't reach database server at `localhost:5432` |
Host name doesn’t exist on this machine (postgres, a Compose service) |
P1001: Can't reach database server at `postgres:5432` |
| Host exists but never answers (firewall, wrong IP) | P1001: Can't reach database server at `10.255.255.1:5432` |
App inside a container using localhost |
P1001: Can't reach database server at `localhost:5432` |
| Something is listening, but it isn’t Postgres (Supabase’s API port) | P1001: Can't reach database server at `127.0.0.1:54321` |
Step 1: find out which one you have
Ask the network directly, with the same host and port as in your error. Node is already installed, so this works on any OS:
node -e "const s=require('net').connect(5432,'localhost');s.setTimeout(5000);s.on('connect',()=>{console.log('open: something is listening');s.destroy()}).on('timeout',()=>{console.log('timeout: no answer at all');s.destroy()}).on('error',e=>console.log(e.code))"Put your host and port into connect(5432,'localhost'). What it printed for each case:
| Output | Meaning | Go to |
|---|---|---|
ECONNREFUSED |
The machine is there, nothing is listening on that port | Nothing listening |
ENOTFOUND |
The host name doesn’t resolve from where you ran it | Docker |
timeout: no answer at all |
Packets go nowhere: firewall, wrong IP, or IPv6 | Timeouts |
open: something is listening |
A server is there. Check it’s Postgres on that port | Wrong service |
Run it from the same place your app runs: inside the container if the app is in a container. Otherwise you’re testing a different network.
Nothing is listening on that port
With my Postgres container stopped, and separately with the right server but the default port 5432 (mine was mapped to 55432), Prisma gave the P1001 above in both cases. The quick check said ECONNREFUSED.
Start the database, and make the port in DATABASE_URL match the one it really listens on. For Docker, the left side of the port mapping is the one your machine uses:
$ docker ps --format "{{.Names}} {{.Ports}}"
nk-pg 0.0.0.0:55432->5432/tcpDATABASE_URL="postgresql://postgres:password@localhost:55432/postgres"Docker: localhost and service names
Most P1001 reports involve Docker, because “localhost” means a different machine depending on where the code runs. I ran Prisma inside a node:24-alpine container on the same Docker network as Postgres (service name postgres, container port 5432, mapped to 55432 on the host):
| From inside the app container | Result |
|---|---|
localhost:5432 |
P1001: the container’s own localhost has no Postgres |
localhost:55432 (the port mapped on the host) |
P1001 |
postgres:55432 (service name + host port) |
P1001: wrong side of the mapping |
postgres:5432 (service name + container port) |
✅ in sync |
host.docker.internal:55432 |
✅ in sync (Docker Desktop) |
And the reverse mistake: running npx prisma migrate on your machine with the URL from your Compose file. postgres only exists inside Docker’s network, so from Windows I got P1001: Can't reach database server at `postgres:5432` (the quick check said ENOTFOUND).
Use the address for where the code runs:
# app running in a container on the same Compose network
DATABASE_URL="postgresql://postgres:password@postgres:5432/postgres"
# prisma CLI running on your machine
DATABASE_URL="postgresql://postgres:password@localhost:55432/postgres"Service name with the container port inside Docker; localhost with the host port outside it. If you run migrations from both places, they need different URLs. Pass the right one per command, or keep two .env files.
No answer at all: firewalls, IPs and Supabase
When nothing answers at all, the quick check prints timeout. Prisma 6’s CLI failed about as fast as it did for a closed port, but a Prisma 7 app waited about 30 seconds first (see the Prisma 7 table below). Usually it’s a firewall or security group not allowing your IP, a VPN, or simply the wrong IP.
For hosted Supabase there’s a common version of this that I couldn’t reproduce here (it needs a hosted project). Per Supabase’s connection docs, the direct host db.<project>.supabase.co is IPv6 unless you pay for the IPv4 add-on. On an IPv4-only network (many home ISPs, some CI runners and hosts) it can’t be reached at all.
For Supabase from an IPv4-only network, use the Session pooler connection string from the dashboard’s Connect panel (aws-…pooler.supabase.com:5432) instead of the direct db.<project>.supabase.co one. If you use the transaction pooler (port 6543) with Prisma, Supabase says to add ?pgbouncer=true. Neither of these was tested here: no hosted project.
Once Prisma connects, Supabase’s API can still refuse your writes with a different code. That one is Supabase error 42501.
Something is listening, but it isn’t Postgres
The local Supabase stack runs the database on 54322 and its HTTP API on 54321. Pointing Prisma at 54321 didn’t give a protocol error. It gave the same P1001, even though the port was open and answering:
Error: P1001: Can't reach database server at `127.0.0.1:54321`
Port 54322 worked. If the quick check says open but Prisma says P1001, compare your port with what’s actually serving Postgres.
Prisma 7 doesn’t always say P1001
In Prisma 7, the CLI (prisma migrate dev) still prints P1001. But in your app, which talks to the database through a driver adapter such as @prisma/adapter-pg, the same problems produced three different errors:
| Problem | Prisma 7 app error |
|---|---|
| Database stopped | PrismaClientKnownRequestError, code: 'ECONNREFUSED', and a message with no reason in it, just the invocation |
| Host name doesn’t resolve | code: 'P1001', “Can’t reach database server at postgres”, meta.driverAdapterError.cause.kind: 'DatabaseNotReachable' |
| Unreachable IP | code: 'P1008', “Operation has timed out”, kind: 'SocketTimeout', after about 30 seconds |
So if you only grep logs for P1001 on Prisma 7, you’ll miss the stopped database entirely. Prisma 6’s client, for comparison, threw PrismaClientInitializationError with the same “Can’t reach database server” text as the CLI.
What didn’t work
How this was tested
Postgres 17 in Docker Desktop 4.94.0 on Windows 11, mapped to port 55432, with Prisma 6.19.3 (prisma db push and a client query) and Prisma 7.10.0 (prisma migrate dev, plus queries through @prisma/adapter-pg). Each failure was produced on purpose: container stopped, wrong port, Compose host name used from Windows, a non-routable IP (10.255.255.1), and the API port of a local Supabase stack (CLI 2.120.0). The container cases ran in node:24-alpine on a user-defined Docker network with Postgres aliased as postgres. Hosted Supabase (IPv6, poolers) wasn’t tested: those notes come from Supabase’s documentation, linked above.
The code for every case above is public, so you can run it yourself: prisma6-noinit and prisma-init in nk-repro.
— N.K., end of entry No.052