Your data

Connecting Supabase to an app builder: IPv6, the pooler and your password

Supabase's direct host is IPv6-only, so many tools fail with ENOTFOUND. Switch to the Supavisor pooler, URL-encode the password and pick the right pool mode.

Founder, Emberblocks

Published 8 min read

On this page
  1. What happened when I connected Supabase to Emberblocks
  2. Why does the Supabase direct host fail with ENOTFOUND?
  3. How do I URL-encode a Supabase password in a connection string?
  4. Which Supabase connection string should an app builder use?
  5. Session mode or transaction mode?
  6. Should a third-party tool connect as the postgres role?
  7. Does the connection need SSL?
  8. How Emberblocks handles a Supabase source

If an app builder, Retool or any other hosted tool cannot connect to your Supabase database, check two things. First, the direct host db.<project-ref>.supabase.co resolves only to an IPv6 address, and many hosted services can only connect over IPv4, so the connection fails with getaddrinfo ENOTFOUND. Use the Supavisor pooler host from the dashboard's Connect dialog instead, with the user name postgres.<project-ref>. Second, if the database password contains characters such as ?, /, %, # or @, percent-encode them before you paste the connection string.

Both problems hit me on the same day, and neither error message pointed at the real cause. This guide explains both, which pooler mode to choose, and which database role a third-party tool should connect as. Supabase details were checked against supabase.com documentation in October 2026.

What happened when I connected Supabase to Emberblocks

On 23 September 2026 I connected a Supabase project to Emberblocks as an external Postgres source. I pasted the direct connection string, and it failed for two independent reasons.

  1. The password broke the URL. The database password contained ?, / and %, unencoded. A connection string is a URL, so ? starts a query string and / ends the host part. The string was not a valid URL at all: the connect wizard answered "Invalid connection string", and psql failed on the same string.
  2. The host had no IPv4 address. With the password fixed, the wizard said "Could not reach the database host". Underneath was ENOTFOUND: db.<project-ref>.supabase.co on port 5432 only had an IPv6 (AAAA) record. My development machine had no IPv6 route, and the Vercel serverless functions that run Emberblocks have no outbound IPv6 either.

The fix took two changes: encode the password with encodeURIComponent, and switch to the Supavisor pooler host aws-0-<region>.pooler.supabase.com, where the user name becomes postgres.<project-ref>. Session mode on port 5432 and transaction mode on port 6543 both connected with node-postgres 8.22.

Why does the Supabase direct host fail with ENOTFOUND?

Supabase's documentation is explicit: direct connections are on IPv6, unless the project has the IPv4 add-on. The host name has an AAAA record and no A record. A client on a network without IPv6 finds no address it can use, and Node.js reports that as getaddrinfo ENOTFOUND db.<project-ref>.supabase.co, which reads like a typo in the host name.

Hosted tools hit this more often than laptops do. Supabase's own IPv4 guide names Retool, Vercel, GitHub Actions and Render as prominent services that only accept IPv4 connections. You can confirm the diagnosis in a few seconds with dig (or nslookup on Windows):

# A record (IPv4): an empty answer means IPv4-only clients cannot connect
dig +short A db.abcdefghijklmnopqrst.supabase.co

# AAAA record (IPv6): an address here means the host is reachable over IPv6
dig +short AAAA db.abcdefghijklmnopqrst.supabase.co
Replace the fake project ref with your own.

There are two fixes. The free one is the shared pooler, covered below, which is IPv4-only on every plan. The paid one is the IPv4 add-on: as of October 2026 it costs $4 a month per database ($0.0055 an hour), is offered on Pro plans and up, and is not dual-stack. Turning it on swaps the AAAA record for an A record, so the direct host becomes reachable over IPv4 only. Supabase warns that toggling it can interrupt direct connections briefly, generally for less than a minute, while DNS changes propagate.

How do I URL-encode a Supabase password in a connection string?

A Postgres connection string is a URI, and the PostgreSQL documentation says any part containing symbols with special meaning must be percent-encoded. Supabase's guide says the same about the password: percent-encode reserved characters such as &, #, ? or a space. In practice that list also covers /, @, : and % itself.

Here is the failure and the fix with a fake project ref and the fake password s3cr?t/pa%ss:

# Broken: raw password, direct IPv6-only host
postgresql://postgres:s3cr?t/pa%ss@db.abcdefghijklmnopqrst.supabase.co:5432/postgres

# Fixed: encoded password, shared pooler in session mode
postgresql://postgres.abcdefghijklmnopqrst:s3cr%3Ft%2Fpa%25ss@aws-0-eu-west-1.pooler.supabase.com:5432/postgres
In the broken string the question mark starts a query string and the slash ends the host, so it does not parse as a URL.

Let the language do the encoding rather than editing the string by hand. In JavaScript, encodeURIComponent handles every reserved character:

const password = "s3cr?t/pa%ss"; // as set in the Supabase dashboard
const encoded = encodeURIComponent(password);
console.log(encoded); // s3cr%3Ft%2Fpa%25ss

const url =
  "postgresql://postgres.abcdefghijklmnopqrst:" + encoded +
  "@aws-0-eu-west-1.pooler.supabase.com:5432/postgres";

Two other ways out: if the tool has separate fields for host, user and password, type the password there, where it is not part of a URL. Or reset the database password in the Supabase dashboard to a long random string of letters and digits.

Which Supabase connection string should an app builder use?

Supabase offers four ways in. The shared pooler host looks like aws-0-eu-west-1.pooler.supabase.com, but the number after aws- is a pooler cluster index, not part of the region name, and a region can have more than one. Supabase says you cannot work out the host from your region: copy it from the Connect dialog at the top of the dashboard.

ConnectionHost and portUserReachable overUse it for
Directdb.<ref>.supabase.co:5432postgresIPv6 (IPv4 with the add-on)Long-running servers that have IPv6
Shared pooler, session modeaws-N-<region>.pooler.supabase.com:5432postgres.<ref>IPv4Persistent backends and tools on IPv4-only networks
Shared pooler, transaction modeaws-N-<region>.pooler.supabase.com:6543postgres.<ref>IPv4Serverless and edge functions
Dedicated pooler (paid plans)db.<ref>.supabase.co:6543postgresIPv6 (IPv4 with the add-on)Transaction mode next to the database
Supabase connection options (October 2026). N is the pooler cluster index.

If you connect as a custom role through the shared pooler, the user name follows the same pattern: <role>.<project-ref>, for example ops_tool.abcdefghijklmnopqrst. The database name stays postgres unless you created another one.

Session mode or transaction mode?

Both pooler modes sit in front of the same database. The difference is how long your client holds a real database connection.

  • Session mode (port 5432) gives your client its own database connection until it disconnects, like a direct connection, so prepared statements and session settings work. Supabase recommends it as the alternative to a direct connection on IPv4-only networks.
  • Transaction mode (port 6543) returns the connection to the pool after each transaction, so many short-lived clients share a few connections. Supabase recommends it for serverless and edge functions. The cost: prepared statements are not supported, cursors live inside one transaction, and session state is lost between transactions, including SET, session-level advisory locks, LISTEN and NOTIFY, and temporary tables.

For an app builder, a simple rule works. If the tool keeps a pool of long-lived connections, use session mode. If it opens connections per request from serverless functions, transaction mode spares your connection limit, as long as its driver does not rely on prepared statements. If a tool reports prepared statement errors on port 6543, move it to 5432 or turn prepared statements off in its driver settings, as Supabase advises.

Should a third-party tool connect as the postgres role?

No. Supabase describes postgres as the default role with admin privileges, and its December 2023 Studio announcement states that it has admin read and write privileges and bypasses Row Level Security. Every RLS policy you wrote for your app's users is ignored for a tool connected as postgres: it can read and change every row of every table.

Supabase's own advice is to create a new user for every service that needs access. Give the tool a dedicated login role with grants on only the tables it needs, a statement timeout and a connection limit; the SQL is in the least-privilege section of the Postgres front-end guide. Two Supabase-specific details: through the shared pooler the role signs in as <role>.<project-ref>, and on a table with RLS enabled, a role that no policy covers sees no rows at all, because Postgres denies by default. Add a policy for the new role on those tables, scoped to what the tool should see.

Does the connection need SSL?

Use it. Supabase accepts unencrypted connections by default for compatibility, and lets you enforce SSL under SSL Configuration in the Database Settings page; enforcement covers Postgres and both poolers, and applying it triggers a quick database restart. With SSL enforced, Supabase recommends verify-full, which checks the certificate against Supabase's CA certificate (downloadable on the same page) and confirms the host name matches. Set it in the tool's connection settings rather than relying on a client default.

How Emberblocks handles a Supabase source

Emberblocks connects to your own Postgres, Supabase included, as one of its data sources next to its built-in database and Airtable. Paste the pooler connection string with the encoded password, then decide which tables accept edits. Rows stay in your Supabase database, and the app reads and writes them live. Tables are read-only until you enable writes for them, and a table needs a primary key before it accepts edits. Details are in the data sources guide and connect your data.

If the Emberblocks wizard answers "Invalid connection string", encode the password. If it answers "Could not reach the database host" for a db.<project-ref>.supabase.co address, switch to the pooler host. Neither message names the cause today, which is why this article exists.

Once connected, the app's own roles decide who sees which tables and rows, enforced on the server. The database role you connect with sets the outer limit; Emberblocks roles narrow it for each app user. The Postgres and Supabase front-end page shows what you can build on top.

Questions people ask

Does Supabase support IPv4 connections?
Yes, through the shared pooler (Supavisor), which is IPv4-only on every plan in both session and transaction mode. The direct host db.<project-ref>.supabase.co is IPv6 unless you add the IPv4 add-on, $4 a month per database as of October 2026.
What is the difference between port 5432 and 6543 on Supabase?
On the shared pooler host, 5432 is session mode and 6543 is transaction mode. On the direct host, 5432 is Postgres itself and 6543 is the dedicated pooler that paid plans get.
Why does my Supabase password break the connection string?
A connection string is a URL, so characters like ?, /, #, @ and % mean something there. Percent-encode the password (encodeURIComponent in JavaScript), type it into a separate password field, or reset it to letters and digits.
Do my RLS policies apply to a tool connected as postgres?
No. The postgres role bypasses Row Level Security. Create a dedicated role for the tool, without the BYPASSRLS attribute, and add policies for it on any table where RLS is enabled, or it will see no rows.

Sources

  1. Supabase docs: connect to your database
  2. Supabase docs: dedicated IPv4 address
  3. Supabase docs: manage IPv4 usage (pricing)
  4. Supabase docs: Postgres SSL enforcement
  5. Supabase docs: Postgres roles
  6. Supabase docs: Row Level Security
  7. Supabase blog: Studio AI Assistant and user impersonation (11 December 2023)
  8. PostgreSQL docs: libpq connection URIs and percent-encoding
  9. PostgreSQL docs: row security policies

Written by

Apostolos builds Emberblocks, a visual app builder for internal tools on your own data, from Thessaloniki, Greece. Spotted something wrong or out of date? Write to hello@emberblocks.com.

Keep reading

Ready to build on your own data?

Connect Postgres, Airtable or a spreadsheet export and publish a working app your team can use today. Builders are always free.