> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Supabase Auth 401: "failed to retrieve Auth config"

> Error: unexpected status 401: {"message":"failed to retrieve Auth config"}

**Error:** `unexpected status 401: {"message":"failed to retrieve Auth config"}`

This guide explains the cause and how to fix it, especially when it appears on **PR preview deployments** (e.g. Vercel Preview).

***

## What this error means

Supabase Auth returns this when a request to an Auth endpoint cannot be validated:

* The **anon key** (or publishable key) in the request is invalid, missing, or for a different project.
* The Auth service cannot load its config for that request, so it responds with 401 and the message above.

Common triggers:

1. **Preview deployments** using wrong or missing Supabase env vars.
2. **Redirect / Site URL** in Supabase not including the preview domain.
3. **Anon key sent as user token** (e.g. `Authorization: Bearer <anon_key>` to `/user`) — Auth expects a session JWT with a `sub` claim; anon key has no `sub` and can lead to 403/401-style failures.

***

## Fix 1: Set Supabase env vars on Preview (Vercel)

For **Vercel Preview** (and any PR/preview environment):

1. In **Vercel** → Project → **Settings** → **Environment Variables**.
2. Add (or copy from Production) for **Preview**:
   * `VITE_SUPABASE_URL` = your project URL (e.g. `https://<project-ref>.supabase.co`)
   * `VITE_SUPABASE_PUBLISHABLE_KEY` = your project’s **anon** (publishable) key
3. Use the **same** values as Production so the preview app talks to the same Supabase project.

If your app uses the auto-generated `src/integrations/supabase/client.ts` with **hardcoded** URL/key (e.g. from Lovable), the built bundle may already contain those values. In that case, 401 on preview can still happen if:

* A different build path injects env at build time and Preview has no (or wrong) env, or
* Redirect/Site URL (below) is the issue.

So ensure Preview has the correct Supabase env vars if any part of the build or runtime depends on them.

***

## Fix 2: Allow your preview URL in Supabase Auth

If the app redirects to the preview domain after login (or Auth checks origin):

1. **Supabase Dashboard** → **Authentication** → **URL Configuration**.
2. **Site URL:** Keep production for production; for testing previews you can temporarily set or add the preview base URL, or use **Redirect URLs**.
3. **Redirect URLs:** Add your preview base URL, e.g.:
   * `https://<preview-slug>-<team>.vercel.app/**`
   * Or a pattern that covers all PR previews (e.g. `https://*.vercel.app/**` if your plan allows).

Save and retry the PR preview.

***

## Fix 3: Supabase Branching overwriting Auth redirect URLs

When using **Supabase Branching** (or `supabase link` to a branch), the “Configuring services for development branch” step can **overwrite** the branch’s Auth config with defaults that only include localhost (e.g. `additional_redirect_urls = ["https://127.0.0.1:3000"]`). That removes the Vercel preview URLs and leads to 401 on the preview deployment.

**Fix:** Add an explicit `[auth]` section in **`supabase/config.toml`** with `additional_redirect_urls` that include **both** local dev URLs and your Vercel preview URL pattern(s), so when config is synced to the branch, the preview URLs are preserved. Example (already in this repo):

```toml theme={null}
[auth]
additional_redirect_urls = [
  "https://127.0.0.1:3000",
  "https://127.0.0.1:8080",
  "https://cloud-migration-path-git-*-jeremy-blooms-projects-93ff6f2c.vercel.app/",
  "https://cloud-migration-path-git-*-jeremy-blooms-projects-93ff6f2c.vercel.app/**",
  "https://cloud-*-migration-path-git-*-jeremy-blooms-projects-93ff6f2c.vercel.app",
  "https://cloud-*-migration-path-git-*-jeremy-blooms-projects-93ff6f2c.vercel.app/**",
]
```

Use your own project/team slug in the patterns. Supabase supports wildcards in redirect URLs (`*`, `**`). After adding this, re-run the branch workflow; the 401 may persist if the workflow still overwrites other Auth settings (e.g. `jwt_issuer`) with local defaults—in that case, re-add the preview URL in **Supabase Dashboard** → **Authentication** → **URL Configuration** → **Redirect URLs** after each branch config run, or adjust the branching pipeline so it does not replace the full Auth config.

***

## Fix 4: Don’t send anon key as user Bearer token

Auth logs may show `403: invalid claim: missing sub claim` when the **anon key** is sent in `Authorization: Bearer` to `/auth/v1/user`. The anon key is a JWT but has no `sub` (user id).

* Use the **session access token** (from `signIn*` / `getSession()`) for user-scoped requests, not the anon key.
* Ensure no code path sends the anon/publishable key in the `Authorization` header when calling `getUser()` or other user endpoints.

***

## Verify

* **Production:** Same app + same Supabase project → no 401.
* **Preview:** After setting Preview env vars and Redirect URLs, deploy again and open the preview URL; login and initial load should no longer return 401 "failed to retrieve Auth config".
* **Supabase Auth logs:** In Dashboard → Logs → Auth, confirm requests from the preview domain use the correct project and no longer get 401 for config retrieval.

***

## Vercel validation (MCP/CLI)

**Validated via Vercel MCP:**

| Check                   | Result                                                                                               |
| ----------------------- | ---------------------------------------------------------------------------------------------------- |
| **Project**             | `nsr-management-system` (id `prj_z2W2giNqsnhGnBMxU5vRZS4DnXuB`)                                      |
| **Team**                | Jeremy Bloom's projects (`team_qjGimov8j4mY2Ojqr7TpL5TI`)                                            |
| **Framework**           | Vite                                                                                                 |
| **Domains**             | encoreos.io, nsr-management-system-\*-.vercel.app                                                    |
| **Latest deployment**   | READY — PR #302 (branch `bolt/debounce-employee-search-*`), build completed (install + `vite build`) |
| **Preview URL pattern** | `nsr-management-syste-git-*-jeremy-blooms-projects-93ff6f2c.vercel.app`                              |

**Environment variables (Preview):**\
The Vercel CLI was not logged in in this environment. To confirm Supabase env vars for **Preview**:

1. **Dashboard:** Vercel → **nsr-management-system** → **Settings** → **Environment Variables**. Ensure `VITE_SUPABASE_URL` and `VITE_SUPABASE_PUBLISHABLE_KEY` exist for **Preview** (not only Production).
2. **CLI (after `vercel login`):**\
   `vercel env ls preview`\
   `vercel env pull --environment=preview` (to test locally with preview vars)

***

## pf\_health\_metrics 401 (Go-http-client)

**Error:** `401` on `GET /rest/v1/pf_health_metrics` with User-Agent `Go-http-client/2.0`

**Cause:** The `pf_health_metrics` table requires authentication. Migration `20260312214212` revokes anon access and adds `pf_health_metrics_anon_deny`, so unauthenticated requests return 401. A caller using `Go-http-client` (e.g. external uptime check, monitoring script, or health probe) is hitting PostgREST without a valid JWT.

**Resolution:**

* **If caller is internal (health/monitoring):** Use a service-role client or authenticated edge function that sends a valid JWT when reading `pf_health_metrics`. Do not call this table from unauthenticated scripts.
* **If caller is external/unknown:** Treat as expected—the table is auth-only. Optionally add a lightweight public health edge function that returns 200 (e.g. `/health`) without exposing metrics for uptime checks.
* **Operational:** Check Supabase logs and deployment configs (Vercel, cron, external probes) for any Go-http-client or health-check requests to `pf_health_metrics` and update them to use an authenticated client or the public health endpoint.

***

## References

* [Supabase Auth error codes](https://supabase.com/docs/guides/auth/debugging/error-codes)
* [Supabase PostgREST auth errors (PGRST301/PGRST302)](https://supabase.com/docs/guides/api/rest/postgrest-error-codes) (invalid JWT / missing Bearer)
* [Vercel environment variables](https://vercel.com/docs/concepts/projects/environment-variables) (Production vs Preview)
