mirror of
https://github.com/supabase/supabase.git
synced 2026-09-03 07:28:20 +08:00
Sync from supabase/troubleshooting
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title = "'Formatting support requests for faster resolution'"
|
||||
date_created = "2026-08-05T20:05:11+00:00"
|
||||
topics = [ "platform" ]
|
||||
keywords = []
|
||||
---
|
||||
|
||||
When you contact Supabase Support, a clear and focused ticket helps our team understand the issue, assess its impact, and begin investigating more quickly.
|
||||
|
||||
If you use an LLM to help write your ticket, give it the information you have gathered, such as your notes, exact error messages, and relevant evidence, combined with the prompt below. The LLM will organise this information into a concise, technically useful support ticket while removing repetition, speculation, and irrelevant details.
|
||||
|
||||
Before submitting the generated ticket, review it carefully to confirm that all details are accurate and that it does not contain passwords, API keys, access tokens, personal data, or other sensitive information. An LLM should help organise the information you provide, it should never invent missing details.
|
||||
|
||||
## Prompt:
|
||||
|
||||
Prioritise clarity over completeness. Include only information that helps the support team understand, reproduce, or investigate the issue.
|
||||
Remove repetition, speculation, generic explanations, attempted diagnoses without evidence, and irrelevant background.
|
||||
|
||||
A shorter ticket containing verified facts is preferable to a longer ticket containing assumptions.
|
||||
|
||||
**Use the following structure:**
|
||||
|
||||
**Summary:** One or two sentences describing the specific problem.
|
||||
|
||||
**Impact:** What is blocked or degraded, who is affected, and whether the issue is ongoing.
|
||||
|
||||
**Expected behaviour:** What should happen.
|
||||
|
||||
**Actual behaviour:** What happens instead, including the exact error message where available.
|
||||
|
||||
**Steps to reproduce:** The shortest reliable sequence of steps. If the issue cannot be reproduced consistently, say so.
|
||||
|
||||
**Environment:** Only relevant identifiers and configuration, such as project reference, region, product or feature, client or library version, and approximate timestamps with timezone. Never include passwords, API keys, tokens, or other secrets.
|
||||
|
||||
**Troubleshooting completed:** Briefly list actions already attempted and their results.
|
||||
|
||||
**Evidence:** Include only relevant logs, queries, screenshots, or request IDs. Use short excerpts instead of full log dumps.
|
||||
|
||||
**Request:** State clearly what assistance or outcome is needed from Support.
|
||||
|
||||
**Requirements:**
|
||||
|
||||
- Aim to keep the ticket under 300 words, excluding essential logs or code.
|
||||
- Put the most important information first.
|
||||
- Do not repeat information across sections.
|
||||
- Do not invent, assume, or infer missing details.
|
||||
- Clearly label any uncertainty.
|
||||
- Preserve exact error messages, timestamps, and identifiers.
|
||||
- If essential information is missing, list no more than three questions under Missing information.
|
||||
- Do not include greetings, apologies, conclusions, or commentary about how the ticket was written.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title = "SQLSTATE 40001 (serialization_failure) in an RPC function causes infinite retries"
|
||||
date_created = "2026-07-27T07:04:18+00:00"
|
||||
topics = [ "functions" ]
|
||||
keywords = []
|
||||
[[errors]]
|
||||
code = "40001"
|
||||
message = "serialization_failure"
|
||||
---
|
||||
|
||||
A custom `raise exception` using SQLSTATE `40001` (`serialization_failure`) in your PL/pgSQL function tells PostgREST the failure is transient, so PostgREST retries the transaction. That floods your logs with duplicates and splits one API request into several independent Postgres transactions.
|
||||
|
||||
This [bug](https://github.com/PostgREST/postgrest/pull/4222) is present in PostgREST 14 and is fixed in PostgREST 16. Follow the [Supabase changelog](/changelog) to get notified when PostgREST 16 is released.
|
||||
|
||||
### How to resolve
|
||||
|
||||
To resolve this, update your Postgres function to use standard exception handling or SQLSTATE codes that map correctly to HTTP status codes.
|
||||
|
||||
**1. Modify the Raise Statement**
|
||||
Replace custom `errcode` assignments with a standard exception or a PostgREST-compliant code:
|
||||
|
||||
- **Standard Fix**: Change `raise exception using errcode = '40001', message = '...';` to `raise exception 'YOUR_ERROR_MESSAGE';`. This defaults to SQLSTATE `P0001`, which does not trigger the retry loop.
|
||||
- **HTTP Mapping**: Use the `PT` [prefix](https://docs.postgrest.org/en/v14/references/errors.html#raise-errors-with-http-status-codes) to map to specific HTTP status codes. For example, to return an HTTP 409, use: `raise sqlstate 'PT409' using message = 'YOUR_ERROR_MESSAGE';`
|
||||
|
||||
**2. Terminate Hanging Backends**
|
||||
Existing looping processes must be stopped manually — fixing the function does not stop transactions already in flight. The repeated error entries in your Postgres logs (Logs Explorer) include a `process_id` field identifying the exact backend raising the error, e.g.:
|
||||
|
||||
```json
|
||||
"process_id": 183165,
|
||||
"sql_state_code": "40001",
|
||||
"user_name": "authenticator"
|
||||
```
|
||||
|
||||
You can also find candidate backends in `pg_stat_activity` by filtering on `authenticator`, the role PostgREST connects as:
|
||||
|
||||
```sql
|
||||
select pid, state, query_start, query
|
||||
from pg_stat_activity
|
||||
where usename = 'authenticator'
|
||||
order by query_start;
|
||||
```
|
||||
|
||||
Match the `pid` against the `process_id` from your logs to confirm you have the right backend, then terminate it from the [SQL editor](/dashboard/project/_/sql/new):
|
||||
|
||||
`SELECT pg_terminate_backend(pid);`
|
||||
|
||||
Alternatively, you can restart the project from the dashboard to clear all hanging backends at once.
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title = "'Permission denied' when deleting the 'cli_login_postgres' role"
|
||||
date_created = "2026-07-20T05:22:16+00:00"
|
||||
topics = [ "cli", "database", "platform" ]
|
||||
keywords = []
|
||||
---
|
||||
|
||||
### **What are CLI Login Roles?**
|
||||
|
||||
In the Supabase ecosystem, specific database roles are generated to facilitate communication between your local development environment and your remote database. Understanding these roles is key to managing your database's security posture.
|
||||
|
||||
**Key Technical Terms:**
|
||||
|
||||
- **cli_login_postgres:** A temporary role automatically created by the Supabase CLI to allow administrative access for tasks like migrations or queries when a database password is not explicitly provided.
|
||||
- **supabase_admin:** An internal system-level role that manages core database infrastructure. It "owns" certain system-generated roles, meaning standard users cannot modify or delete them.
|
||||
- **rolvaliduntil:** A PostgreSQL attribute that sets an expiration timestamp for a role's password. In this context, these roles are typically set to expire within a few hundred seconds of creation.
|
||||
- **NOLOGIN:** A role attribute that prevents a role from being used to establish a new connection to the database, effectively disabling it while keeping the record in the system catalog.
|
||||
|
||||
---
|
||||
|
||||
### **Understanding the Problem: "Permission Denied"**
|
||||
|
||||
If you attempt to execute `DROP ROLE cli_login_postgres` via the SQL Editor or a standard database connection, you will encounter a "permission denied" error. Even when logged in as the `postgres` user, you lack the administrative authority to remove this specific role because it is managed by the internal `supabase_admin` system.
|
||||
|
||||
**Why the role persists:**
|
||||
The role is part of a managed lifecycle. While you can mitigate risk by setting the role to `NOLOGIN`, the record remains in the `pg_roles` table. Furthermore, because the Supabase CLI depends on this role for passwordless authentication, it will automatically recreate the role the next time a CLI command is run without a password.
|
||||
|
||||
---
|
||||
|
||||
### **How to Resolve: Permanently Removing the Role**
|
||||
|
||||
Standard SQL commands are insufficient for roles administered by the platform. To remove the role from the catalog entirely, you must use the Supabase Management API.
|
||||
|
||||
1. **Generate an Access Token:** Obtain a Personal Access Token from your Supabase Dashboard account settings.
|
||||
2. **Execute the API Delete Request:** Use a `DELETE` request to the CLI login-role endpoint. This informs the management system to drop the `cli_login_postgres` role (and its read-only counterparts) using its elevated system permissions.
|
||||
```bash
|
||||
curl -X DELETE "https://api.supabase.com/v1/projects/your_project/cli/login-role" \
|
||||
-H "Authorization: Bearer <your-personal-access-token>"
|
||||
```
|
||||
3. **Verify the Removal:** Run the following query in your SQL Editor to confirm the role has been cleared:
|
||||
```sql
|
||||
select rolname from pg_roles where rolname = 'cli_login_postgres';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Prevention: Avoiding Role Recreation**
|
||||
|
||||
To ensure the role is not recreated in the future, you must change how you interact with the Supabase CLI. The role is only generated when the CLI runs a command against a linked project without a database password.
|
||||
|
||||
To prevent recreation, always provide your database password using one of these methods:
|
||||
|
||||
- **Environment Variables:** Set the `SUPABASE_DB_PASSWORD` variable in your local shell or `.env` file.
|
||||
- **Command Flags:** Use the password flag (typically `-p` or `--password`) when executing commands:
|
||||
```bash
|
||||
supabase db query --linked -p 'your_database_password' "SELECT 1;"
|
||||
```
|
||||
|
||||
By providing the password, the CLI authenticates directly as the `postgres` user rather than provisioning a temporary `cli_login_postgres` role.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title = "Postgres error: 'could not access status of transaction' when PostgREST runs LISTEN"
|
||||
date_created = "2026-07-29T09:05:06+00:00"
|
||||
topics = [ "database" ]
|
||||
keywords = [ "postgrest" ]
|
||||
---
|
||||
|
||||
## The error
|
||||
|
||||
You'll see this in your database logs:
|
||||
|
||||
- **Error:** `could not access status of transaction`
|
||||
- **Detail:** `Could not open file "pg_xact/[ID]": No such file or directory`
|
||||
- **Application:** PostgREST (shown as `PostgREST 13.0.5` or similar)
|
||||
- **Command:** `LISTEN`
|
||||
|
||||
If you see the first error message without the pg_xact detail, or outside PostgREST, it may be a different issue.
|
||||
|
||||
## What's happening
|
||||
|
||||
This is an upstream Postgres [bug](http://postgresql.org/message-id/flat/VE1PR03MB531295B1BDCFE422441B15FD92499%40VE1PR03MB5312.eurprd03.prod.outlook.com) but affects PostgREST. The notification queue gets stuck and tries to access old transaction IDs that no longer exist.
|
||||
|
||||
## Fix
|
||||
|
||||
Run this command in the [SQL editor](/dashboard/project/_/sql/new):
|
||||
|
||||
```sql
|
||||
select pg_notification_queue_usage();
|
||||
```
|
||||
|
||||
This clears the stuck queue. Your Data API will become responsive again, and the errors should stop.
|
||||
|
||||
## If it happens again
|
||||
|
||||
Run the command above again.
|
||||
|
||||
If you upgrade to PostgREST v14.8+, the logs will include a `HINT` that tells you to run `SELECT pg_notification_queue_usage();`. You can upgrade PostgREST and Postgres in [Infrastructure Settings](/dashboard/project/_/settings/infrastructure).
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title = "Storage: Unexpectedly high usage or 'exceed_storage_size_quota' errors"
|
||||
topics = [ "cli", "database", "storage", "studio" ]
|
||||
keywords = []
|
||||
---
|
||||
|
||||
If you're observing unexpectedly high storage usage or receiving 'exceed_storage_size_quota' errors, even after deleting files, it's often due to orphaned storage objects.
|
||||
|
||||
**Why Does This Happen?**
|
||||
This issue arises when storage objects are deleted directly from `storage.objects` or `storage.buckets` tables using SQL queries, bypassing the Supabase Storage API. Deleting database rows in this manner does not remove the corresponding physical files, leading to orphaned objects that continue to consume storage space.
|
||||
|
||||
**How to Avoid This Issue:**
|
||||
|
||||
- Always delete storage objects using the official Supabase Storage API. This can be done via client libraries (e.g., `storage.from('example_bucket').remove(['example_folder/example_object.txt'])`) or through the [Supabase Studio Storage UI](/dashboard/project/_/storage/buckets).
|
||||
- Never manually remove rows directly from `storage.objects` or `storage.buckets` tables using SQL, as this will not delete the associated physical files and will result in orphaned objects.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title = "Supavisor connection error: FATAL: (EAUTHQUERY) unsupported or invalid secret format"
|
||||
date_created = "2026-09-02T12:05:14+00:00"
|
||||
topics = [ "database", "supavisor" ]
|
||||
keywords = []
|
||||
[[errors]]
|
||||
code = "EAUTHQUERY"
|
||||
message = "unsupported or invalid secret format"
|
||||
|
||||
---
|
||||
|
||||
If you are observing a `FATAL: (EAUTHQUERY) unsupported or invalid secret format` error when connecting to the Supavisor pooler (ports 5432 or 6543), it typically indicates an issue with the database role's credentials.
|
||||
|
||||
### Why does this happen?
|
||||
|
||||
This error occurs when the custom Postgres role used for the connection has an expired `VALID UNTIL` timestamp. When a role is expired, the internal authentication query used by Supavisor returns a null password secret, which prevents the pooler from completing the SCRAM authentication process.
|
||||
|
||||
### How to resolve this issue
|
||||
|
||||
You can verify and update the role's expiration status via the [SQL editor](/dashboard/project/_/sql/new):
|
||||
|
||||
1. Identify if the role has expired by running the following query:
|
||||
```sql
|
||||
select rolname, rolvaliduntil, rolvaliduntil < now() as expired
|
||||
from pg_authid
|
||||
where rolname = 'example_role';
|
||||
```
|
||||
2. If the `expired` column returns true, update the role to extend or remove the expiration limit:
|
||||
```sql
|
||||
ALTER ROLE example_role VALID UNTIL 'infinity';
|
||||
```
|
||||
3. Re-attempt the connection using your Supavisor connection string.
|
||||
|
||||
If the issue persists or the role is not expired, reach out to [supabase.help](https://supabase.help/) for assistance.
|
||||
Reference in New Issue
Block a user