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 registered in project settings or you're missing proper authentication headers. Fix: Add your frontend domain to Supabase's CORS allowlist in Project Settings > API > CORS, or ensure requests include the Authorization header with a valid JWT token.

---

Real Console Error Messages

Watch for these exact errors in your browser DevTools Console:

``` Access to XMLHttpRequest at 'https://your-project.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. ```

``` Fetch error: Failed to fetch TypeError: Failed to fetch (anonymous) @ main.js:42 ```

``` No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors'. ```

``` Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be either 'true' or 'false'. ```

``` supabase: error creating user: Error: Failed to sign up user with email. Status 403: Forbidden ```

---

Broken Code vs. Fix

Problem #1: Domain Not in CORS Allowlist

BROKEN: ```javascript // Your frontend at https://myapp.com tries to query Supabase const { data, error } = await supabase .from('users') .select('*') .eq('id', userId); // Returns: CORS policy blocked by browser ```

FIXED: ```javascript // Step 1: Add your domain to Supabase Project Settings // Go to: Project Settings > API > CORS Configuration // Add: https://myapp.com (and http://localhost:3000 for dev)

// Step 2: Your code remains the same - CORS headers now allowed const { data, error } = await supabase .from('users') .select('*') .eq('id', userId); // Now works: browser receives proper Access-Control-Allow-Origin header ```

Problem #2: Missing or Invalid Auth Headers

BROKEN: ```javascript // Using supabase-js client without proper initialization import { createClient } from '@supabase/supabase-js';

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

await supabase.auth.signUp({ email: 'user@example.com', password: 'password123' }); // Request fails: missing valid Authorization header ```

FIXED: ```javascript // Initialize with correct anon key from Supabase import { createClient } from '@supabase/supabase-js';

const supabase = createClient( process.env.VITE_SUPABASE_URL, // https://your-project.supabase.co process.env.VITE_SUPABASE_ANON_KEY // Get from Project Settings > API > Project Keys );

await supabase.auth.signUp({ email: 'user@example.com', password: 'password123' }); // Works: Authorization header automatically included by SDK ```

Problem #3: Direct Fetch Without Headers (Bypassing SDK)

BROKEN: ```javascript // Calling Supabase REST API directly without auth const res = await fetch( 'https://your-project.supabase.co/rest/v1/users', { method: 'GET' } ); // CORS error: missing Authorization and apikey headers ```

FIXED: ```javascript // Include required headers for direct API calls const res = await fetch( 'https://your-project.supabase.co/rest/v1/users', { method: 'GET', headers: { 'Authorization': Bearer ${SESSION_JWT_TOKEN}, 'apikey': process.env.VITE_SUPABASE_ANON_KEY, 'Content-Type': 'application/json' } } ); // Works: all required CORS headers present ```

---

Still broken? Check these too

1. Environment Variables Not Loaded: Verify your .env.local file exists with VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY. Restart dev server after adding them. Most common at 2am—the key is literally invisible if not loaded.

2. RLS Policies Blocking Requests: Even with CORS fixed, Row Level Security policies might reject your query. Check Project > Authentication > Policies to ensure your policy allows SELECT for your user role.

3. Trailing Slash or URL Mismatch: Ensure Supabase URL in settings exactly matches what you're querying (protocol, domain, no trailing slash). https://proj.supabase.co ≠ https://proj.supabase.co/

---

Quick Action Checklist

  • [ ] Project Settings > API > CORS Configuration: add your production domain + localhost
  • [ ] Project Settings > API > Project Keys: copy correct anon key to env file
  • [ ] Restart dev server after env changes
  • [ ] Check Network tab in DevTools—look for response headers like Access-Control-Allow-Origin
  • [ ] Test with supabase-js SDK first before debugging direct fetch calls
  • ---

    Related Guides

  • [Supabase Authentication Failures](/?guide=supabase-auth-errors)
  • [RLS Policy Debugging](/?guide=supabase-rls-issues)
  • ---

    Official Documentation

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

    ---

    Found a different variation? Drop it in the comments—CORS errors are environment-specific and your fix might save someone else's 2am emergency.

    🔥 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