跳到正文
DEV Community· nils44344·· 3 小時前AI 評分63

Prisma P1001 無法連接 localhost:5432:成因與排查方法

Prisma P1001: Can't reach database server at localhost:5432

AI 導讀

Prisma P1001 表示 Prisma 未能建立資料庫連線,文章整理了不同連線故障的錯誤表現與排查方法。作者使用 Prisma 6.19.3、7.10.0 和 Postgres 17 測試,涵蓋資料庫未啟動、連接埠或主機名錯誤、防火牆,以及連到非 PostgreSQL 服務等情況。

正文

The error:

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

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/tcp
DATABASE_URL="postgresql://postgres:password@localhost:55432/postgres"

✅ With the container running and port 55432 in the URL, prisma db push reached the database and synced the schema.

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

❌ Changing the password or the database name. P1001 happens before Prisma ever sends them. In all five cases here, the credentials were never checked.

❌ Using the host-side port inside Docker. postgres:55432 and localhost:55432 both failed inside the container. The host port only exists on the host.

❌ Trusting "something is listening". Supabase's API port was open and still gave P1001. An open port isn't necessarily Postgres.

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.


Originally published, with updates as new versions ship, at nilaykabariya.blog. Written with AI assistance; every error and fix was reproduced on a real machine before it was written up.

來源:DEV Community · dev.to