Supabase: CORS errors from browser [2026 fix]

Browser blocks Supabase API calls due to missing CORS headers. Add your domain to Supabase project settings or use proper auth headers.

Supabase: CORS errors from browser [2026 fix]

TL;DR

Cause: Your browser is blocking requests to Supabase because your domain isn't authorized in project CORS settings. Fix: Add your domain to Supabase project settings under API → CORS, or ensure you're using authenticated requests with valid session tokens.

---

Exact Error Messages (Real Console Output)

``` 1. Access to XMLHttpRequest at 'https://xxxxx.supabase.co/rest/v1/users' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

2. Fetch API cannot load https://xxxxx.supabase.co/rest/v1/posts. The request client is not permitted to access the resource. CORS header 'Access-Control-Allow-Origin' missing.

3. XMLHttpRequest at 'https://xxxxx.supabase.co/auth/v1/user' from origin 'https://myapp.com' blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header is '' which must be 'https://myapp.com' (with http/https but not both).

4. Preflight request to https://xxxxx.supabase.co/rest/v1/data returned HTTP 403. The CORS protocol does not allow specifying a wildcard (any) origin when the request's credentials mode is 'include'.

5. Failed to load resource (net::ERR_FAILED). The 'Access-Control-Allow-Credentials' header was missing when request's credentials mode is 'include'. ```

---

The Problem: Broken Code vs. Fixed Code

❌ Broken: Missing CORS Configuration + Wrong Request

```javascript // Frontend: localhost:3000 const { data, error } = await supabase .from('users') .select('*') .eq('id', 123);

// Backend call without auth header (if using direct REST) const response = await fetch( 'https://xxxxx.supabase.co/rest/v1/users?id=eq.123', { method: 'GET', headers: { 'Content-Type': 'application/json', // MISSING: Authorization header // MISSING: apikey header } } ); ```

Supabase Project Settings: CORS list is empty or doesn't include localhost:3000.

✅ Fixed: Add Domain to CORS + Include Auth Headers

Step 1: Update Supabase Project Settings 1. Go to [supabase.com](https://app.supabase.com) → Your Project → Settings → API 2. Find "CORS" section 3. Add your origins: ``` http://localhost:3000 https://myapp.com https://www.myapp.com ``` (One per line. Use full protocol + domain. No trailing slashes.)

Step 2: Use Supabase Client Library (Recommended)

```javascript // Uses built-in CORS handling + auto auth headers import { createClient } from '@supabase/supabase-js';

const supabase = createClient( 'https://xxxxx.supabase.co', 'YOUR_ANON_KEY' // Safe to expose in browser );

const { data, error } = await supabase .from('users') .select('*') .eq('id', 123); ```

Step 3: If Using Direct REST API Calls

```javascript // Include BOTH required headers const response = await fetch( 'https://xxxxx.supabase.co/rest/v1/users?id=eq.123', { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': Bearer ${session?.access_token}, // For authenticated users 'apikey': 'YOUR_ANON_KEY' // Always required } } );

const data = await response.json(); ```

---

Why This Happens

Supabase uses browser CORS security to prevent unauthorized apps from accessing your data. The browser enforces this before your request reaches Supabase's servers. You must either:

1. Whitelist your domain in project CORS settings (for browser apps), OR 2. Send proper auth headers if making direct REST calls, OR 3. Use Supabase's JavaScript client which handles both automatically

---

Still broken? Check these too

1. Protocol Mismatch

  • CORS setting: https://myapp.com
  • Your app: http://myapp.com ← Different protocols = blocked
  • Fix: Use same http/https in both places, or add both variants to CORS
  • 2. Trailing Slashes or Ports

  • CORS setting: https://myapp.com:3000/ ← Extra trailing slash
  • Your app: https://myapp.com:3000 ← No slash
  • Fix: Remove trailing slashes. Don't include paths in CORS origins
  • For localhost: Use exact port (e.g., http://localhost:3000, not http://localhost)
  • 3. Stale Configuration or Browser Cache

  • You added domain to CORS but still seeing error
  • Fix: Hard refresh browser (Ctrl+Shift+R / Cmd+Shift+R), clear console, try again
  • Give Supabase 30 seconds to propagate changes
  • ---

    Related Guides

  • [Supabase authentication setup errors](/guide=auth-errors)
  • [RLS policies blocking all queries](/guide=rls-debugging)
  • Official Documentation

    [Supabase CORS Configuration Guide](https://supabase.com/docs/guides/api/cors)

    ---

    Found a different variation? Drop it in the comments — we'll add it to this guide so others don't waste 2am debugging time.

    🔥 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