
The first time I hit ECONNREFUSED connecting n8n to PostgreSQL, I spent 40 minutes checking the password. The password was never the problem. Most devs get stuck in the same loop – credentials look right, the database is running, and n8n still refuses to connect. The actual cause is almost always one of three things, and this page covers all of them.
If your n8n PostgreSQL node fails to connect even though the credentials look correct, the problem is almost never SQL logic. In real n8n setups, connection failures are caused by SSL configuration, network access restrictions, or how n8n establishes connections at runtime – especially in n8n Cloud and Docker-based deployments.
This guide focuses only on fixing PostgreSQL connection failures in n8n. It covers SSL errors, IP allowlists, Docker hostname mistakes, misleading credential tests, and why connections appear “randomly broken” in production.
If it doesn’t connect, this page fixes it. Nothing else.
Start Here – The n8n PostgreSQL Debug Decision Tree
Use this before reading anything else. Find your exact error, get your exact fix. No guessing.
ECONNREFUSED 127.0.0.1:5432 |
You’re using localhost inside Docker. n8n is pointing at itself, not your database container. | → Fix 1 |
ECONNREFUSED ::1:5432 |
Same cause, IPv6 variant. Node.js resolved localhost to ::1 instead of 127.0.0.1. |
→ Fix 1 |
read ECONNRESET |
PostgreSQL accepted the TCP connection then immediately closed it. Almost always an SSL mismatch. | → Fix 2 |
SSL SYSCALL error: EOF detected |
SSL handshake started and was aborted. Wrong sslmode or server certificate rejected. |
→ Fix 2 |
no pg_hba.conf entry for host |
PostgreSQL received the connection but its access control file doesn’t allow your IP or user. | → Fix 3 |
password authentication failed |
Wrong credentials, OR pg_hba.conf uses md5 but n8n sent scram-sha-256. Check credentials first. |
→ Fix 3 |
ETIMEDOUT / connection timed out |
Port 5432 is blocked by a firewall or security group. PostgreSQL never received the request. | → Fix 3 |
EADDRINUSE 127.0.0.1:5432 |
Another process already owns port 5432. Run lsof -i :5432 to find and kill it. |
→ Kill conflicting process |
Credential test passes, workflow fails |
Normal behaviour, not a bug. Credential test only verifies authentication — not SSL, routing, or runtime execution. | → Section 2 |
Works sometimes, fails randomly |
Not random. n8n opens a brand new connection per execution. The intermittent pattern is a stateless execution issue. | → Section 4 |
| Same Docker Compose as n8n | Use the service name as the host, not localhost. If your service is named postgres, use Host: postgres. |
→ Fix 1 |
| Local machine, n8n in Docker (Mac / Windows / WSL) |
Use host.docker.internal. On Linux without Docker Desktop, use the Docker bridge IP: 172.17.0.1. |
→ Fix 1 |
| Supabase | Use the direct connection URL on port 5432, not the pooler (port 6543). Set sslmode=require. |
→ Platform: Supabase |
| Railway | Use ${{Postgres.PGHOST}} env var. Crash loops with ECONNREFUSED ::1:5432 happen when n8n starts before Postgres is ready. |
→ Platform: Railway |
| AWS RDS | Requires sslmode=verify-full and the AWS global CA bundle. Without it you’ll get SSL SYSCALL EOF. |
→ Platform: RDS |
| DigitalOcean Managed DB | Download and paste the CA cert. Add your n8n server IP to Trusted Sources. Both steps are required. | → Platform: DO |
| GCP CloudSQL | No public IP by default. Use Cloud SQL Auth Proxy as a sidecar, or enable public IP and whitelist n8n’s IP in CloudSQL’s authorised networks. | → Platform: GCP |
| n8n Cloud (not self-hosted) | Database must be publicly reachable. localhost and 127.0.0.1 will never work from n8n Cloud. Add n8n’s outbound IPs to your allowlist. |
→ Fix 1 |
1. Quick Diagnosis
Most n8n PostgreSQL connection failures – especially in Cloud and Docker setups — are caused by SSL misconfiguration, blocked IPs, or misunderstanding how credential tests differ from runtime execution. Not SQL bugs. Always validate connections using SELECT 1 inside a workflow, not in the credential test panel.
Why does n8n PostgreSQL connection fail even when credentials are correct?
Because credentials alone are not the connection. In production environments, PostgreSQL connections fail for three dominant reasons:
| Cause | What Fails at Runtime | How to Fix |
|---|---|---|
| SSL misconfiguration | TLS handshake rejected | Enable SSL and set the provider-required sslmode |
| IP restrictions | Network traffic blocked | Allow inbound traffic from n8n’s IP |
| Runtime execution context | Credential test ≠ real connection | Validate inside a workflow using SELECT 1 |
Production Validation (Non-Negotiable)
Always validate PostgreSQL connectivity using this inside a workflow node — not the credential test:
SELECT 1; -- Confirms the database you actually connected to at runtime SELECT current_database(), inet_client_addr(); -- Shows which DB and IP you're connecting from
Run this inside a workflow, not in the credential test. If SELECT 1 fails at runtime, the issue is connection-level, not SQL logic.
Once SELECT 1 succeeds reliably, connection issues are ruled out. If your PostgreSQL node executes successfully but no rows are inserted or updated, the problem is workflow logic or database constraints – not connectivity: n8n PostgreSQL Node Executes but Data Doesn’t Update

2. PostgreSQL Credential Test Passes but Workflow Fails?
This is the most common source of confusion in n8n PostgreSQL setups. It is normal behaviour, not a bug.
The credential test only verifies authentication — whether the username and password are correct. It does not check:
- Network routing at execution time
- Runtime SSL negotiation
- Execution-context access rules
| What It Is | What It Actually Checks |
|---|---|
| Credential test | “Can I log in?” — authentication only |
| Workflow execution | “Can I actually connect, negotiate SSL, and run a query?” — the real connection |
A passing credential test does not guarantee runtime connectivity. If workflows fail while credential tests pass, the issue is SSL, network routing, or execution context — not your data or query logic.
If your workflow connects successfully but INSERT ... ON CONFLICT fails to update existing rows, that is an UPSERT-specific behaviour and not a connection issue: n8n PostgreSQL UPSERT Not Updating Existing Records
3. Fix 1 – Why “localhost” Does Not Work for PostgreSQL in n8n
Because localhost means this machine, and n8n is often not running on the same machine as PostgreSQL. Inside a Docker container, localhost refers to the container itself — not your host machine, and not another container.
Docker Compose – The Most Common Mistake
# ❌ Wrong - this will give you ECONNREFUSED every time Host: localhost Host: 127.0.0.1
# ✅ Correct - use the service name from your docker-compose.yml # If your postgres service is named "postgres", use: Host: postgres # If it's named "db", use: Host: db
Docker Compose automatically creates a shared network between services in the same file. Containers on that network can reach each other using their service name as the hostname.
n8n in Docker, PostgreSQL on Your Local Machine (Mac / WSL / Windows)
If PostgreSQL is installed directly on your machine and n8n is running in Docker, localhost still won’t work. Docker containers can’t reach the host via loopback. Use this instead:
# ✅ Mac and Windows (Docker Desktop) Host: host.docker.internal # ✅ Linux (without Docker Desktop) # Find your Docker bridge IP: ip addr show docker0 # Typical result: 172.17.0.1 — use that as your host
Also make sure PostgreSQL’s pg_hba.conf allows connections from the Docker subnet (usually 172.17.0.0/16), otherwise you’ll hit no pg_hba.conf entry even after fixing the hostname.
n8n Cloud
n8n Cloud can never access your local machine’s localhost or 127.0.0.1. The database must be publicly reachable with proper SSL and an allowlist that includes n8n’s outbound IPs. You can find n8n Cloud’s outbound IPs in their documentation under instance settings.
4. Fix 2 – SSL Configuration and Why It Causes Silent Failures
SSL misconfiguration is the single most common cause of n8n PostgreSQL failures — and the hardest to diagnose because the error messages don’t always make it obvious. PostgreSQL will silently reject a connection if the SSL expectations don’t match on both sides.
The Four sslmode Values – What Each One Means
sslmode=disable # No TLS — rarely allowed in production managed databases sslmode=require # TLS required, certificate not validated sslmode=verify-ca # TLS required + CA certificate verified sslmode=verify-full # TLS required + CA verified + hostname must match
Provider SSL Requirements
| Provider | Required sslmode | CA Certificate Needed? |
|---|---|---|
| Supabase | require |
No |
| AWS RDS | verify-full |
Yes — global-bundle.pem from AWS |
| Neon | require |
No |
| Railway | require |
No |
| DigitalOcean Managed DB | require |
Yes — download from DO control panel |
| GCP CloudSQL | verify-ca or Proxy |
Yes — server CA from CloudSQL console |
| Self-hosted Docker | disable (internal only) |
No |
If SSL or IP rules fail, PostgreSQL will silently reject the connection – which is why these failures are so easy to misdiagnose as a credentials problem.
5. How n8n Actually Connects to PostgreSQL – Why Failures Feel Random?
Understanding this removes most confusion about why n8n PostgreSQL issues feel intermittent.
- n8n executions are stateless
- A new PostgreSQL connection is opened per node execution
- Authentication occurs on every run
- SSL and network rules are re-validated every time
Every workflow execution: ├─ Opens a new TCP connection ├─ Authenticates (username + password) ├─ Negotiates SSL ├─ Executes the query └─ Closes the connection
This is why credential tests pass, workflows fail, and the problem appears intermittent. It is not random — it is an execution-time connection failure that gets triggered every time the node runs.
Because n8n opens a new database connection per execution, high workflow concurrency amplifies SSL failures, connection limits, and pooling issues. For production-scale setups: n8n PostgreSQL Optimization for High Concurrency, Connection Pooling & Performance
6. Real n8n PostgreSQL Error Logs – What Each One Is Telling You
These are real error outputs from n8n and PostgreSQL, with a plain-English translation of what each one means and what to do.
connect ECONNREFUSED 127.0.0.1:5432
NodeOperationError: connect ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1606:16)
Translation: n8n tried to connect to port 5432 on itself. PostgreSQL is in a separate container or on a separate host. Fix: use the Docker service name or the correct external hostname instead of localhost.
n8n crash loop – ECONNREFUSED ::1:5432
Initializing n8n process There was an error initializing DB connect ECONNREFUSED ::1:5432 Last session crashed Initializing n8n process There was an error initializing DB connect ECONNREFUSED ::1:5432
Translation: n8n is crash-looping because it can’t reach its database. Common on Railway and Docker when PostgreSQL starts after n8n. Fix: add depends_on with a healthcheck in Docker Compose, or set DB_POSTGRESDB_CONNECTION_TIMEOUT to give PostgreSQL time to boot before n8n tries to connect.
FATAL: no pg_hba.conf entry for host
2025-01-15 09:23:11 UTC [38] FATAL: no pg_hba.conf entry for host "172.18.0.3", user "n8n_user", database "n8n", SSL off
Translation: PostgreSQL can see the connection attempt but its access control file has no rule allowing it. The IP 172.18.0.3 is n8n’s Docker network IP. Fix: add host all all 172.18.0.0/16 scram-sha-256 to pg_hba.conf, or allow the full Docker subnet.
read ECONNRESET (SSL mismatch)
Couldn't connect with these settings Retry read ECONNRESET
Translation: TCP connection established, then immediately killed. This is PostgreSQL closing the connection because it requires SSL and n8n didn’t offer it — or offered the wrong version. Fix: enable SSL in n8n credentials and set the correct sslmode for your provider.
7. Platform-Specific Fixes
The generic fixes above solve most setups. But each managed provider has specific quirks that cause n8n connections to fail even when the general config looks correct.
Supabase
The most common Supabase mistake: using the pooler URL (port 6543) instead of the direct connection URL (port 5432). n8n’s PostgreSQL node requires the direct connection.
# ❌ Wrong — pooler URL (for serverless functions, not n8n) Host: aws-0-us-east-1.pooler.supabase.com Port: 6543 # ✅ Correct — direct connection Host: db.YOUR-PROJECT-REF.supabase.co Port: 5432 SSL: enabled sslmode: require
Railway
Railway ECONNREFUSED crash loops are almost always a startup order problem — n8n starts and tries to connect before PostgreSQL is ready. Use Railway’s internal environment variables directly:
DB_POSTGRESDB_HOST=${{Postgres.PGHOST}}
DB_POSTGRESDB_PORT=${{Postgres.PGPORT}}
DB_POSTGRESDB_DATABASE=${{Postgres.PGDATABASE}}
DB_POSTGRESDB_USER=${{Postgres.PGUSER}}
DB_POSTGRESDB_PASSWORD=${{Postgres.PGPASSWORD}}
DB_POSTGRESDB_SSL_ENABLED=true
AWS RDS
RDS requires sslmode=verify-full and the AWS global CA bundle. Without the CA cert you’ll get SSL SYSCALL error: EOF detected.
# In n8n PostgreSQL credentials: SSL: enabled sslmode: verify-full SSL CA: (paste the contents of global-bundle.pem)
Download the CA bundle from: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem. Also verify your RDS security group allows inbound on port 5432 from your n8n server’s IP.
DigitalOcean Managed Database
DigitalOcean requires SSL with a CA certificate for all managed databases. Without it, connections return ECONNRESET silently.
# 1. Go to your DO database → Overview → Download CA certificate # 2. In n8n PostgreSQL credentials: SSL: enabled SSL CA: (paste the downloaded CA cert content)
Also add your n8n server IP to the database’s Trusted Sources list in DigitalOcean. Without this, connections are blocked at the network level before SSL is even negotiated.
GCP CloudSQL
GCP CloudSQL has no public IP by default. Most ETIMEDOUT errors are because n8n is trying to reach an IP that isn’t publicly routable.
# Option 1 — Public IP (simpler)
# Enable public IP in CloudSQL, add n8n's IP to authorised networks
# Set sslmode=verify-full with the server CA cert from CloudSQL console
# Option 2 — Cloud SQL Auth Proxy (recommended for production)
services:
cloudsql-proxy:
image: gcr.io/cloudsql-connectors/cloud-sql-proxy:latest
command: --address 0.0.0.0 YOUR-PROJECT:REGION:INSTANCE
n8n:
depends_on:
- cloudsql-proxy
environment:
DB_POSTGRESDB_HOST: cloudsql-proxy
DB_POSTGRESDB_PORT: 5432
Related Guides
Once the connection is stable, debug deeper issues separately:
- n8n PostgreSQL node runs successfully but nothing updates
- n8n PostgreSQL UPSERT not updating existing records
- n8n PostgreSQL Optimization for High Concurrency, Connection Pooling & Performance
- How to Use n8n to Sync Databases — Beginner-Friendly No-Code Integration Guide
- How to Use n8n to Integrate Slack — Beginner Friendly Automation Guide
Final Takeaway
If n8n cannot reliably connect to PostgreSQL, no workflow logic will behave predictably.
Fix SSL, network access, and runtime execution context first. Use the debug decision tree at the top of this page to route directly to your issue. Only after the connection is confirmed stable should you debug updates, UPSERTs, or performance problems.



