Prisma P1001 "Can't Reach Database Server": Fix It

Prisma P1001 means nothing answered at the host and port in DATABASE_URL: the database is down, the host is wrong (often localhost in Docker) or blocked.
P1001 is a network error, not a Prisma bug and not a password problem. Prisma tried to open a TCP connection to the address in your URL and got no answer in time. I've seen it on every kind of setup: a local Postgres that wasn't started, a Docker Compose app pointing at localhost, a CI job running migrations against a private database, and a serverless database that was asleep. The API behind this site runs Prisma on PostgreSQL, and I use the steps below whenever a migration or a deploy throws P1001.
Key takeaways
- Test the network first with
nc -zv host 5432from the same machine or container as the app. If that fails, Prisma will too. - In Docker,
localhostis the container itself. Use the Compose service name, such asdb, as the host. - Postgres listens only on localhost by default. Remote connections need
listen_addresses, apg_hba.confrule and an open firewall port. - Managed databases often need
sslmode=require, an IPv4 or pooler hostname, or a longerconnect_timeoutfor a sleeping database. - P1000 is a different error: the server answered and rejected the login.
The error
Error: P1001: Can't reach database server at `localhost:5432` Please make sure your database server is running at `localhost:5432`.
Read the host and port in the message carefully. Half the time they aren't what you expected, because a different .env file, a CI secret or a shell variable won. Prisma prints exactly what it used.
Step 1: Can this machine reach that address at all?
Run the check from where Prisma runs: your laptop, the server, inside the container, or in the CI job.
nc -zv db.example.com 5432
# Connection to db.example.com 5432 port [tcp/postgresql] succeeded!
# inside a container that has no nc:
docker compose exec api node -e "require('net').connect(5432,'db').on('connect',()=>{console.log('ok');process.exit()}).on('error',e=>console.log(e.code))"
ECONNREFUSED/ "Connection refused": the host is up but nothing listens on that port. Postgres is stopped or listens elsewhere.- Hangs, then times out: a firewall is dropping packets, or the host is unreachable from this network.
ENOTFOUND: the hostname doesn't resolve here. Typo, a private DNS name, or an IPv6-only name on an IPv4 network.
Cause 1: Postgres isn't running
sudo systemctl status postgresql sudo ss -tlnp | grep 5432 docker compose ps db
If it's stopped, start it and read why it stopped: sudo journalctl -u postgresql -n 50 or docker compose logs db. A full disk is a common reason Postgres refuses to start, see No space left on device.
Cause 2: localhost inside Docker
This is the one I see most. Each container has its own network namespace, so localhost inside the app container is the app container, not the database. Use the service name from docker-compose.yml:
services:
db:
image: postgres:17
api:
environment:
DATABASE_URL: postgresql://app:pw@db:5432/app # not localhost
depends_on:
db:
condition: service_healthy
The reverse catches people too: running prisma migrate from your laptop against a database in Compose needs localhost and a published port (ports: ["127.0.0.1:5432:5432"]), while the app inside Compose needs db. Keep two URLs, one per context.
The condition: service_healthy part matters as well. Without a healthcheck on db, the app can start and run migrations before Postgres accepts connections, and you get P1001 only on the first boot.
Cause 3: Postgres only listens on localhost
If the app or your migration runs on another machine, Postgres has to accept outside connections. Three things must all be true:
# 1. postgresql.conf (needs a restart, not a reload) listen_addresses = 'localhost,10.0.0.5' # this server's private IP # 2. pg_hba.conf: allow only the app's network host app app 10.0.0.0/24 scram-sha-256 # 3. firewall: open 5432 to that network only sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp sudo systemctl restart postgresql
Don't open 5432 to the whole internet. Bots scan it constantly. For a one-off connection from your laptop, use an SSH tunnel instead: ssh -L 5433:127.0.0.1:5432 user@server, then connect to localhost:5433. If you run Postgres in Docker on a server with ufw, read why Docker bypasses ufw before publishing the port.
Cause 4: Managed database quirks
- SSL required. Most managed Postgres services reject plain connections. Add
?sslmode=requireto the URL. - IPv6-only hostnames. Supabase's direct connection hostname resolves to IPv6 unless you buy the IPv4 add-on. Many VPS and CI networks have no IPv6 route, so it hangs. Use the connection pooler hostname from the dashboard instead.
- Sleeping databases. Neon and similar services suspend idle compute. The first connection wakes it, which can take longer than Prisma's default 5 second connect timeout. Add
&connect_timeout=15. - Private hostnames. Railway's
*.railway.internaland other private-network names only resolve inside that platform. Running migrations from GitHub Actions needs the public URL. - IP allowlists. Some providers only accept listed IPs. CI runners change IP every run, so either allow the runner's range or migrate from a host with a fixed IP.
Cause 5: The wrong URL won
Prisma connected to the address it printed, so check where that came from:
echo "$DATABASE_URL" # a shell variable overrides .env grep -rn DATABASE_URL .env* prisma.config.ts 2>/dev/null
In Prisma 7 the CLI reads the URL from prisma.config.ts, and .env isn't loaded unless you import dotenv/config there. If the URL is undefined you get a different error; my Prisma 7 upgrade guide covers that setup. At runtime, Prisma 7 connects through a driver adapter, so the same network problem may show up as the driver's ECONNREFUSED or timeout instead of P1001. The fixes are identical.
Once it connects
- P1000 means the network works and the login was rejected. Follow my password authentication failed guide.
- Run migrations in the deploy with
prisma migrate deploy, from a machine that can reach the database, before switching traffic to the new release. - Size your pool. More app instances means more connections; see too many clients already.
Frequently asked questions
What does Prisma error P1001 mean?
Prisma couldn't open a network connection to the database host and port in your URL. Either the database isn't running, the host or port is wrong for the place Prisma runs, or a firewall or network rule blocks the connection.
Why do I get P1001 in Docker but not locally?
Your URL probably uses localhost. Inside a container, localhost is the container itself. Replace it with the database's Compose service name, for example db, and make the app wait for the database healthcheck.
How do I fix P1001 with Supabase?
The direct database hostname is IPv6 by default, and many networks can't reach IPv6. Use the pooler connection string from the Supabase dashboard, which works over IPv4, and keep sslmode=require.
What's the difference between P1001 and P1000?
P1001 means Prisma couldn't reach the server at all. P1000 means it reached the server and the server rejected the username or password. Fix the network for P1001 and the credentials or pg_hba.conf for P1000.
Can I increase Prisma's connection timeout?
Yes. Add connect_timeout in seconds to the connection string, for example ?connect_timeout=15. It helps with databases that wake from sleep, but it won't fix a blocked port or wrong host.
Want this fixed and deployed properly?
I fix broken Node.js, Next.js and NestJS apps and set up Prisma, Postgres and Docker so deploys and migrations just run. See my bug fixing service, all web development services, or contact me with the full error.
Written by
MD Rakibul Islam Rakib
Full-stack developer, DevOps engineer and Linux system administrator with 5+ years of production experience. I deploy, harden and fix servers and web apps for clients worldwide, and everything in this article runs on real servers I manage, including this site.
- Prisma P1001
- Can't reach database server
- DATABASE_URL
- Docker Compose Postgres
- Supabase
- Neon
- PostgreSQL


