Supabase: CORS errors from browser [2026 fix]

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

Supabase CORS Errors from Browser – Emergency 2am Fix

TL;DR

Cause: Your browser is blocking requests to Supabase because the domain isn't configured in CORS settings or you're missing proper authentication headers. Fix: Add your frontend domain to Supabase project settings under Authentication → URL Configuration, or configure your Supabase client correctly with proper headers.

---

Real Console Error Messages

You'll see one or more of these exact errors in your browser console:

``` Access to XMLHttpRequest at 'https://your-project.supabase.co/rest/v1/table_name' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. ```

``` CORS error: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode (include) is 'include'. ```

``` Failed to load resource: the server responded with a status of 401 (Unauthorized) Access to XMLHttpRequest at 'https://your-project.supabase.co/rest/v1/...' from origin 'https://myapp.com' has been blocked by CORS policy. ```

``` TypeError: Failed to fetch (Reason: CORS policy: No 'Access-Control-Allow-Origin' header) ```

``` Syntax error: Unexpected token < in JSON at position 0 (Actually a 403/401 HTML error page, not JSON – CORS blocked it) ```

---

Broken Code vs. Exact Fix

Problem 1: Missing Domain in CORS Configuration

❌ Broken Setup: ```javascript // Your app at https://myapp.com makes requests to Supabase // But myapp.com is NOT added to Supabase allowed origins

const { data, error } = await supabase .from('users') .select('*'); // Result: CORS error in browser ```

✅ Fix: Go to Supabase Dashboard → Your Project → Authentication → URL Configuration

Add these URLs to "Redirect URLs" and "Site URL":

  • http://localhost:3000 (local dev)
  • https://myapp.com (production)
  • https://www.myapp.com (with www, if applicable)
  • https://*.vercel.app (if using Vercel preview deployments)
  • Then your exact same code works: ```javascript const { data, error } = await supabase .from('users') .select('*'); // ✅ Now works – domain is whitelisted ```

    ---

    Problem 2: Not Using Supabase Client Correctly

    ❌ Broken (Raw fetch without auth): ```javascript const response = await fetch( 'https://your-project.supabase.co/rest/v1/users?select=*', { method: 'GET' } ); // Missing auth headers + no CORS headers = blocked ```

    ✅ Fix (Use Supabase client): ```javascript import { createClient } from '@supabase/supabase-js';

    const supabase = createClient( 'https://your-project.supabase.co', 'your-public-anon-key' );

    const { data, error } = await supabase .from('users') .select('*'); // ✅ Client handles CORS + auth automatically ```

    ---

    Problem 3: RLS Policies Blocking Anonymous Access

    ❌ Broken (Supabase client configured but RLS denies anonymous): ```javascript const supabase = createClient('...', 'anon-key'); const { data, error } = await supabase .from('users') .select('*'); // Returns: 403 Forbidden – RLS policy requires authentication ```

    ✅ Fix (Enable public access in RLS or authenticate user): ```javascript // Option A: Disable RLS for this table (dev only!) // In Supabase Dashboard → Table Editor → Click table → "Disable RLS"

    // Option B: Create RLS policy allowing public read -- In Supabase SQL Editor: ALTER TABLE users ENABLE ROW LEVEL SECURITY; CREATE POLICY "Allow public read" ON users FOR SELECT TO anon USING (true);

    // Option C: Authenticate user first const { error } = await supabase.auth.signInWithPassword({ email: 'user@example.com', password: 'password' }); const { data } = await supabase.from('users').select('*'); // ✅ Authenticated request bypasses anon restrictions ```

    ---

    Still Broken? Check These Too

    1. Supabase Service Role Key Exposed in Frontend – Never put service_role_key in browser code. Use only public anon key and authenticate users properly. If you exposed it, regenerate immediately in project settings.

    2. Environment Variables Not Loaded – Verify SUPABASE_URL and SUPABASE_ANON_KEY are actually available to your app (check with console.log(process.env.SUPABASE_URL)). Many frameworks require REACT_APP_ or VITE_ prefix.

    3. Using Old Supabase Client Version – Upgrade to latest: npm install @supabase/supabase-js@latest. Older versions had inconsistent CORS handling. Note: I'm uncertain if v1 vs v2 client have different CORS defaults in all edge cases – consult [official Supabase changelog](https://github.com/supabase/supabase-js/releases).

    ---

    Related Guides

  • [Supabase Row-Level Security (RLS) errors explained](/?guide=supabase-rls-errors)
  • [Database connection pooling & timeout fixes](/?guide=connection-pooling)
  • ---

    Official Resources

  • [Supabase CORS Configuration Docs](https://supabase.com/docs/guides/api/cors)
  • [Supabase Authentication Setup](https://supabase.com/docs/guides/auth/overview)
  • [Row Level Security (RLS) Guide](https://supabase.com/docs/guides/database/postgres/row-level-security)
  • ---

    Found a different variation? Drop it in the comments

    If you hit a CORS error with a unique stack trace or scenario (e.g., specific framework, mobile webview, API gateway), share it below – we'll add it to this guide.
    🔥 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