> For the complete documentation index, see [llms.txt](https://docs.coupler.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coupler.io/destinations/categories/database/supabase/common-issues.md).

# Common Issues

## Connection issues

<details>

<summary>Coupler.io can't connect to my Supabase database</summary>

Work through these in order:

* **Use the Session pooler string**, not the direct connection. The direct endpoint resolves to IPv6, which Coupler.io can't reach without the project's IPv4 add-on. See [Which connection string to use](#which-connection-string-to-use).
* **Check the username format.** Pooler connections use `postgres.[project-ref]`, not plain `postgres`. Copying only the password from the dashboard and typing the user manually is the most common mistake.
* **Reset the database password** if authentication fails — it's separate from your Supabase login. Find it in **Project Settings → Database → Database password**.
* **Confirm the project isn't paused.** See [My data flow suddenly stopped running](#my-data-flow-suddenly-stopped-running-after-a-quiet-period).
* **Check Network Restrictions** if you've enabled them. See below.

</details>

<details>

<summary>I use Network Restrictions — which IPs do I allowlist?</summary>

Supabase's **Network Restrictions** (Project Settings → **Database** → Network Restrictions) is the equivalent of a firewall allowlist, and it uses **CIDR notation** rather than bare IPs. Add both Coupler.io addresses as `/32` ranges:

* `34.123.243.115/32`
* `34.170.96.92/32`

Notes specific to Supabase:

* Restrictions are enforced on **all connection routes** — the shared pooler as well as direct connections. Allowlisting only for direct connections and then switching Coupler.io to the pooler is not a workaround.
* If your direct connection resolves to IPv6, Supabase asks you to add IPv6 CIDRs too. Coupler.io only needs the two IPv4 entries above, but leaving your existing IPv6 entries in place keeps your own tooling working.
* An `update` via the CLI **replaces** the whole list unless you pass `--append`. Adding Coupler.io's IPs with a plain update can silently drop your own.
* You need Owner or Admin permissions on the project to change restrictions.

</details>

<details>

<summary>Connection worked, then started being refused after a few failed attempts</summary>

This is Supabase-specific and often mistaken for a Coupler.io problem. Supabase runs Fail2ban in front of the database: a couple of failed authentication attempts in a row (for example, saving a Coupler.io destination with a stale password and retrying) **temporarily bans the client IP**.

* Bans clear automatically after about **30 minutes**.
* To lift one immediately, go to **Project Settings → Database** and use **Unban IP**, or run `supabase network-bans remove` with the CLI.
* Fix the credentials before retrying, otherwise the ban is reapplied.

{% hint style="info" %}
If a data flow fails repeatedly on connection, stop re-running it. Each failed attempt can extend the ban and make the destination look permanently broken.
{% endhint %}

</details>

<details>

<summary>Connection times out during the data flow run</summary>

A timeout mid-run (not at the credentials step) means the query outlived a statement timeout or the instance ran out of headroom. Supabase applies its own timeout defaults, so this behaves differently from a self-hosted PostgreSQL server:

* The `postgres` role has no explicit statement timeout but is capped by a **2-minute global default**. Large loads can hit this.
* Raise it for the role Coupler.io connects as, from the SQL Editor:

  ```sql
  alter role postgres set statement_timeout = '10min';
  ```

  Session-level `set statement_timeout` only works over session mode or a direct connection — another reason not to use the transaction pooler.
* Check **Observability → Database Connections** for pool saturation. Compute size caps both max connections and max pooler clients, so a busy app plus a large Coupler.io load can exhaust them.
* Split very large flows into several sources, or filter at the source level.

</details>

## Project state

<details>

<summary>My data flow suddenly stopped running after a quiet period</summary>

Free Plan Supabase projects are **paused after \~7 days of low activity**, and a paused project accepts no database connections at all. Every scheduled Coupler.io run counts as activity, so an active flow normally keeps a project awake — but a paused or newly imported flow won't.

* Restore the project from the Supabase dashboard. Paused Free projects are restorable for 90 days after pausing.
* Re-run the data flow after the project is fully restored; credentials and schema are unchanged.
* Upgrade to Pro to stop automatic pausing.

</details>

## Data issues

<details>

<summary>Data flow fails with a column name error</summary>

Supabase enforces a **63-character limit** on column names. If your source data has field names longer than 63 characters, the data flow will fail.

This is a known issue with sources like **Facebook (Meta) Ads** and **Stripe**, which sometimes produce long field names.

To fix this:

* Use the **Transformations** step in your data flow to rename the affected columns to shorter names before they reach PostgreSQL
* Be careful when editing transformations — changes are saved automatically without a confirmation prompt, so double-check before navigating away

{% hint style="danger" %}
Transformation changes in Coupler.io save automatically. Accidental edits can change your column structure without warning. Review your transformation settings carefully if your data flow suddenly starts failing.
{% endhint %}

</details>

<details>

<summary>Append mode breaks after a source schema change</summary>

Same behavior as any PostgreSQL destination: in Append mode, Coupler.io writes into the existing table structure, so new source columns cause the run to fail.

Add the columns yourself in the Supabase **SQL Editor** before the next run:

```sql
alter table your_schema.your_table add column new_column text;
```

After that, Coupler.io populates them normally. Using the Table Editor works too, but SQL is faster for several columns at once.

</details>

<details>

<summary>Data types are wrong in the destination table</summary>

Coupler.io detects and enforces column types from the source. Mismatches happen when the table already exists with different types.

* In **Replace** mode, drop the table and let Coupler.io recreate it cleanly on the next run
* In **Append** mode, check that existing column types match what Coupler.io writes

{% hint style="warning" %}
Supabase-specific: dropping and recreating a table also drops its **RLS policies, grants, indexes, and foreign keys**, and any Data API access other services rely on. If the table is used by your app, alter the column types instead of dropping the table.
{% endhint %}

</details>

## Permission errors

<details>

<summary>Permission denied when creating a schema or table</summary>

Supabase's default `postgres` role is an admin role (not a superuser) and can create schemas and tables, so this error almost always means you connected with a **custom, limited role**. Grant it:

```sql
GRANT CREATE ON DATABASE postgres TO your_user;
GRANT CREATE ON SCHEMA your_schema TO your_user;
GRANT INSERT ON TABLE your_schema.your_table TO your_user;
```

{% hint style="info" %}
For Coupler.io to create schemas and tables automatically, the role needs CREATE at both the database and schema level — not just INSERT on an existing table. Note that PostgreSQL 15+ (which Supabase runs) no longer grants CREATE on the `public` schema to everyone, so custom roles need an explicit grant even for `public`.
{% endhint %}

</details>

<details>

<summary>Coupler.io's tables trigger an "RLS disabled in public" security warning</summary>

Tables Coupler.io creates are plain PostgreSQL tables with **Row Level Security disabled**. If they live in the `public` schema, Supabase's Security Advisor flags them, and they're readable through the Data API by anyone with your anon key.

Two options:

* **Load into a dedicated schema** (for example, `coupler`) that isn't exposed through the Data API. This is the recommended setup for analytics data.
* **Enable RLS** on each table after the first run. RLS doesn't block Coupler.io's writes, since the role it connects as bypasses RLS:

  ```sql
  alter table public.your_table enable row level security;
  ```

</details>

<details>

<summary>My table loaded successfully but I can't see it in the dashboard or API</summary>

Not an error. If Coupler.io created the table in a schema other than `public`, the Table Editor only shows it once you select that schema from the schema dropdown, and the Data API ignores it entirely until you add the schema to **Project Settings → API → Exposed schemas** and grant `usage` on it to the API roles.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.coupler.io/destinations/categories/database/supabase/common-issues.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
