Supabase: CORS errors from browser [2026 fix]

Browser blocks Supabase requests due to missing CORS headers. Fix: Configure allowed origins in project settings or use proper API key scope.

Supabase: CORS errors from browser [2026 fix]

TL;DR

Cause: Your browser is blocking cross-origin requests to Supabase because the project's CORS policy doesn't allow your app's origin.

Fix: Add your frontend URL to Supabase project's API settings under "CORS" or verify you're using the anon (public) API key, not the service role key.

---

Exact Error Messages You'll See

Open your browser console (F12 → Console tab) and look for one of these:

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

``` CORS error: Access to XMLHttpRequest at 'https://[PROJECT-ID].supabase.co/auth/v1/signup' from origin 'https://myapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ```

``` Failed to load resource: the server responded with a status of 403 (Forbidden) Response header missing: Access-Control-Allow-Origin ```

``` TypeError: Failed to fetch ```

``` No 'Access-Control-Allow-Credentials' header in the response when credentials mode is 'include' ```

---

Broken Code vs. Exact Fix

Problem 1: Missing CORS Configuration in Project Settings

Broken (won't work from browser): ```javascript // Your React/Vue/Next.js app at http://localhost:3000 import { createClient } from '@supabase/supabase-js'

const supabase = createClient( 'https://xyz123.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // anon key )

// Browser blocks this automatically if origin not in CORS list const { data } = await supabase .from('users') .select('*') ```

Fixed (add origin in Supabase dashboard):

1. Go to Supabase Dashboard → Your Project → Settings → API 2. Scroll to "CORS Configuration" 3. Add your origins: ``` http://localhost:3000 https://myapp.com https://www.myapp.com ``` 4. Click Save 5. Restart your development server 6. Code stays the same; browser now allows the request

Problem 2: Using Service Role Key in Browser (Critical Security Issue)

Broken (will fail AND expose secrets): ```javascript const supabase = createClient( 'https://xyz123.supabase.co', 'sbp_service_role_secret_key_do_not_use_in_browser' // ❌ WRONG ) ```

Fixed (always use anon key in frontend): ```javascript const supabase = createClient( 'https://xyz123.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // ✅ anon key from Settings → API → Anon key ) ```

Problem 3: Credentials Mode Mismatch

Broken (if using custom fetch): ```javascript fetch('https://xyz123.supabase.co/rest/v1/users', { method: 'GET', headers: { 'Authorization': 'Bearer ' + anonKey, 'Content-Type': 'application/json' } // Missing credentials handling }) ```

Fixed (explicit credentials mode): ```javascript fetch('https://xyz123.supabase.co/rest/v1/users', { method: 'GET', headers: { 'Authorization': 'Bearer ' + anonKey, 'Content-Type': 'application/json' }, credentials: 'include' // Include cookies if using sessions }) ```

---

Still broken? Check these too

1. Browser cache is stale — Hard refresh (Ctrl+Shift+R on Windows/Linux, Cmd+Shift+R on Mac) or clear browser cache. CORS configuration changes take 30-60 seconds to propagate.

2. Origin mismatch between development and production — If testing from 127.0.0.1:3000 but registered localhost:3000, browsers treat them as different origins. Register both or use your actual hostname.

3. Supabase project is paused — Free tier projects pause after 1 week of inactivity. Check your project status in the dashboard; click "Resume" if needed. This returns 403 errors that look like CORS issues. See [Supabase billing and project limits](/guide=supabase-paused-project) for details.

---

Related Guides

  • [Understanding JWT auth tokens in Supabase](/guide=supabase-jwt-explained)
  • [Row Level Security (RLS) permission denied errors](/guide=supabase-rls-403)
  • ---

    Official Documentation

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

    ---

    Version Note: This guide covers Supabase client library v2.x (current as of 2026). Behavior in v1.x may differ; check your package.json version if issues persist.

    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