Connection refused or timeout when connecting to Postgres
Why psql, ORMs and pg_dump get ECONNREFUSED or time out against SupaHost, and how to connect through the Business SSH tunnel at 127.0.0.1:5432 instead.
What you see
One of these, from psql, an ORM, a GUI client or pg_dump:
psql: error: connection to server at "acme.supahost.space" (203.0.113.10), port 5432 failed: Connection timed out
Error: connect ECONNREFUSED 127.0.0.1:5432
channel 2: open failed: administratively prohibited: open failed
ssh: connect to host acme.supahost.space port 22: Connection timed out
Why it happens
SupaHost never exposes Postgres to the internet. On every instance, port 5432 is bound to 127.0.0.1 inside the VM, so nothing outside the VM can reach it directly. Pointing a client at acme.supahost.space:5432 or app-one.acme.supahost.space:5432 will always time out or be refused.
The only direct route is an SSH tunnel, available on Business and Enterprise. Your SSH client forwards a local port to 127.0.0.1:5432 on the VM, and your tools connect to the local end. Each message above points to a different missing piece:
| Message | Meaning |
|---|---|
| Timeout on port 5432 | You're connecting to the public hostname. Use the tunnel. |
ECONNREFUSED 127.0.0.1:5432 |
Nothing is listening locally: the tunnel isn't running, or it uses another local port. |
administratively prohibited |
The tunnel's destination isn't exactly 127.0.0.1:5432. Keys only allow that one target, so localhost:5432 is refused. |
| Timeout on port 22 | SSH isn't open for this instance: it isn't on Business or Enterprise, or it has no SSH key yet. |
How to fix it
Add your public key in Dashboard → your project → Connect tab → SSH & CLI (field "Public key", button "Add key"). It's active within about a minute. Port 22 only opens once at least one key exists.
Open the tunnel in its own terminal and leave it running:
ssh -N -L 5432:127.0.0.1:5432 [email protected]The user is always
supahost.-Nmeans "forward only", so the command appears to hang. That's expected.In another terminal, connect to the local end with the string from Connect → Database → Show connection string:
psql "postgresql://postgres:<password>@127.0.0.1:5432/p_app_one" -c "select now();"If local port 5432 is taken, forward another one (
-L 55432:127.0.0.1:5432) and use port 55432 in the connection string.If your client runs inside Docker on your machine,
127.0.0.1is the container, not your laptop. Usehost.docker.internalas the host, or run the tunnel inside the container.For long-running servers, keep the tunnel up with a process supervisor or
autosshand reconnect when it drops.
On SupaHost
- On Builder and Pro there is no direct Postgres access. Use the Data API from your app, Studio's SQL editor for ad-hoc SQL, the MCP server's
execute_sqlfor AI agents, and Dashboard → your project → Backups tab for apg_dumpexport. Permission denied (publickey)means the key isn't on the instance yet or you used a user other thansupahost.- Browser, mobile and serverless apps shouldn't connect to Postgres at all. Use supabase-js against
https://app-one.acme.supahost.space.