Supabase: CORS errors from browser [2026 fix]

Browser blocks Supabase API calls due to missing CORS headers. Fix: Add your domain to Supabase project settings or use proper RLS policies.

Supabase CORS Errors from Browser – 2am Emergency Fix

TL;DR

Cause: Your browser is blocking requests to Supabase because your domain isn't whitelisted in CORS settings or you're missing proper authentication headers. Fix: Add your domain to Supabase's CORS allowlist in Project Settings → API → CORS Configuration, or switch from anonymous requests to authenticated requests with proper RLS policies.

---

Real Console Error Messages

Here are exact errors you'll see in browser DevTools (F12 → Console):

``` 1. Access to XMLHttpRequest at 'https://xxxxx.supabase.co/rest/v1/users' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control checks: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

2. Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxxx.supabase.co/rest/v1/posts. (Reason: CORS header 'Access-Control-Allow-Origin' missing). Status code: (null).

3. Failed to fetch (TypeError) Under 'Network' tab: GET https://xxxxx.supabase.co/rest/v1/data 403 Forbidden – CORS policy: Response to preflight request doesn't pass access control checks.

4. Uncaught (in promise) TypeError: Failed to fetch network error (no preflight response from server)

5. The CORS protocol does not allow specifying a wildcard ('*') for credentials. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. ```

---

Broken Code vs. Exact Fix

❌ BROKEN: Anonymous request with credentials

```javascript // This fails because you're sending credentials without proper CORS setup const { data, error } = await supabase .from('users') .select('*') .eq('id', userId);

// Network call includes credentials by default in some setups fetch('https://xxxxx.supabase.co/rest/v1/users', { method: 'GET', credentials: 'include', // ← CORS blocks this headers: { 'apikey': 'YOUR_ANON_KEY' } }); ```

✅ FIXED: Proper authentication + CORS configuration

Option A: Add domain to CORS allowlist (simplest)

1. Go to [Supabase Dashboard](https://app.supabase.com) → Your Project → Settings → API → CORS Configuration 2. Add your domain: ``` http://localhost:3000 https://yourdomain.com https://www.yourdomain.com ```

```javascript // Now this works—no credentials needed const { data, error } = await supabase .from('users') .select('*') .eq('id', userId); ```

Option B: Use authenticated requests with RLS (recommended for production)

```javascript // Sign in first await supabase.auth.signInWithPassword({ email: user@example.com, password: password });

// Now requests include session automatically—no CORS issues const { data, error } = await supabase .from('users') .select('*') .eq('id', userId);

// Direct fetch also works with proper auth header const res = await fetch('https://xxxxx.supabase.co/rest/v1/users', { method: 'GET', headers: { 'Authorization': Bearer ${session.access_token}, 'apikey': 'YOUR_ANON_KEY' } // NO credentials: 'include' }); ```

---

Still Broken? Check These Too

1. Wrong API Key – Verify you're using your project's anon key (not service key). Service keys should never be exposed to browsers. Check Settings → API Keys in Supabase dashboard.

2. Localhost vs. 127.0.0.1 – If CORS allowlist has localhost:3000 but you're accessing 127.0.0.1:3000, that's two different origins. Add both, or use localhost consistently.

3. Environment Variable Timing – If using .env.local, ensure Next.js/Vite has restarted after you added the Supabase key. CORS errors often hide missing/stale API keys.

4. Stale Browser Cache – Hard refresh (Ctrl+Shift+R or Cmd+Shift+R) to clear preflight cache. Browser caches failed preflight requests.

5. RLS Policy Blocks Everything – If you enabled RLS but policy denies all reads (USING (false)), you'll get 403 errors that look like CORS. Check your RLS policy in Table Editor → Policies.

---

Version-Specific Behavior

I'm uncertain whether Supabase changed CORS defaults between v1.x and v2.x client libraries in 2025–2026. Check your supabase-js version:

```bash npm list @supabase/supabase-js ```

Older versions (<1.25.0) may have stricter CORS validation. If you're on an old version and adding domains doesn't help, try upgrading:

```bash npm install @supabase/supabase-js@latest ```

---

Related Guides

  • [Supabase RLS policies not working](/?guide=supabase-rls-debug)
  • [Fix auth token issues in production](/?guide=supabase-token-refresh)
  • ---

    Official Documentation

    [Supabase CORS Configuration](https://supabase.com/docs/guides/api#cors) [Supabase Authentication & RLS](https://supabase.com/docs/guides/auth/row-level-security)

    ---

    Found a different variation? Drop it in the comments.

    🔥 0d
    LIVE
    PlanetScale rage spiking Vercel pricing complaints Railway gaining fast Supabase happiness rising Resend loved by devs PlanetScale rage spiking Vercel pricing complaints Railway gaining fast Supabase happiness rising
    DEVELOPER PAIN RADAR // Loading...

    Developers complain.
    Opportunities appear.

    We track what developers are struggling with today — and what opportunities that creates.

    guides today
    avg happiness
    🔥 Pain
    📖 Guides
    🔭 Explore
    👤 Mine
    🔥 Pain Radar — rage scores today
    ↗ share
    💡 Opportunity Feed — pain = market gap
    📈 Tool Momentum
    all scores →
    📖 Latest Guide
    all guides →
    📖 All Guides
    📊 Tool Scores
    + Submit
    📰 Hacker News
    ➕ Submit a Tool
    ← back