Connections

Fixing Supabase IPv6 connection failures (ENETUNREACH)

Atomart· April 18, 2026· updated July 13, 2026· 6 min read

Fixing Supabase IPv6 connection failures (ENETUNREACH)

You try to connect to a Supabase database over db.<project-ref>.supabase.co and the connection hangs or dies with:

connect ENETUNREACH 2600:1f18:...:5432

The address in the error is IPv6. That is the whole problem: the direct database host resolves to an IPv6 address, and your network cannot route IPv6.

Why this happens

Supabase moved direct database connections to IPv6. The direct host db.<ref>.supabase.co returns an AAAA (IPv6) record. If your client, your ISP, your CI runner, or your container network is IPv4-only, the OS cannot open a socket to that address and returns ENETUNREACH — "network is unreachable."

This is not an authentication problem and not a Supabase outage. The route does not exist. See ENETUNREACH for the decoded error.

Confirm it is IPv6

Resolve the host and look at what you get:

dig AAAA db.your-project-ref.supabase.co +short
# or
nslookup db.your-project-ref.supabase.co

If you get an IPv6 address (colons, e.g. 2600:1f18:...) and no reachable IPv4, that is the failure. Confirm you have no IPv6 route:

curl -6 https://ifconfig.co        # fails or times out on IPv4-only networks
curl -4 https://ifconfig.co        # returns your IPv4 address

Supabase's pooler (Supavisor) is dual-stack and answers on IPv4. Switch the host from the direct database host to the pooler host:

# Direct (IPv6-only):
postgresql://postgres:PW@db.abcdefgh.supabase.co:5432/postgres

# Pooler (IPv4 reachable):
postgresql://postgres.abcdefgh:PW@aws-0-<region>.pooler.supabase.com:6543/postgres

Three things change with the pooler, and each one bites people:

  • The username becomes postgres.<project-ref>, not plain postgres. Miss this and you get password authentication failed even with the right password.
  • The port is 6543 for the transaction pooler (or 5432 on the session pooler host).
  • Transaction mode does not support session-level features like prepared statements or LISTEN/NOTIFY. For a migration that is usually fine; for some workloads use the session pooler.

The connection string builder assembles the pooler URL from your project ref and region so you do not fat-finger the username. Background on why the pooler exists: connection pooler.

Fix 2 — Buy an IPv4 add-on

Supabase sells a dedicated IPv4 address for the direct host as a paid add-on. Enable it and db.<ref>.supabase.co gets an A record. This keeps the direct connection with session features, but costs money and is unnecessary if the pooler works for you.

Fix 3 — Give the client IPv6

If you control the network, enabling real IPv6 connectivity fixes it at the source. On many home and cloud networks you cannot, which is why the pooler is the usual answer. Supabase documents both paths under connecting to your database.

Which fix for which situation

  • Local dev on an IPv4-only ISP → pooler.
  • CI runner (GitHub Actions historically IPv4-only) → pooler.
  • You need session-level Postgres features and control billing → IPv4 add-on.
  • You run your own IPv6-capable infrastructure → fix the route.

A note on migrations

A migration opens connections to two projects: the source and the destination. Either host can be IPv6-only, so set both to pooler URLs if either network leg is IPv4-only. Too many parallel connections through the pooler can also raise too many connections — keep the migration's connection count modest. The connect source and connect destination docs show where each string goes.

FAQ

Why did my connection work last year and break now?

Supabase moved direct database connections to IPv6 by default. If your code used db.<ref>.supabase.co and your network is IPv4-only, the string that resolved to a reachable address before now resolves to an unreachable IPv6 address. Switch to the pooler host or enable the IPv4 add-on.

Is the pooler slower than a direct connection?

For request/response query workloads the difference is negligible, and the pooler often helps by reusing connections. The trade-off is not speed — it is that transaction-mode pooling drops session-level features like prepared statements and LISTEN/NOTIFY. Use the session pooler if you need those.

Does ENETUNREACH mean my password or project is wrong?

No. ENETUNREACH is a network-layer error raised before any authentication happens — your machine has no route to the IPv6 address. A wrong password produces password authentication failed instead, which only appears after the socket connects.

Atomart

Founder, SupaMigrate

Builder of SupaMigrate. Works on Postgres, Supabase, and the unglamorous parts of database migration — schema replay, auth hash preservation, and connection pooling.

Related reading