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 authentication headers.

Supabase CORS Errors from Browser – Production Fix

TL;DR

Cause: Your browser is blocking requests to Supabase because the origin domain isn't in your project's CORS allowlist. Fix: Add your production domain to Supabase Project Settings → API → CORS allowed origins, or use proper session-based authentication instead of exposing your anon key.

---

Real Console Error Messages

You'll see one of these exact errors at 2am:

``` Access to XMLHttpRequest at 'https://xxx.supabase.co/rest/v1/users?select=*' from origin 'https://myapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ```

``` CORS error: Failed to fetch TypeError: Failed to fetch ```

``` 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'. ```

``` [Supabase] Cannot read property 'error' of undefined Fetch error: 0 ```

``` supabase-js error: {'status':0,'statusText':'','url':'https://xxx.supabase.co/rest/v1/...'} ```

---

The Problem: Broken vs. Fixed Code

❌ BROKEN CODE (Causes CORS errors)

```javascript // Your Nuxt/React/Vue app - domain: https://myapp.com import { createClient } from '@supabase/supabase-js'

const supabase = createClient( 'https://xxx.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' )

// Browser makes request from myapp.com to xxx.supabase.co // Supabase doesn't recognize myapp.com → CORS BLOCKED const { data, error } = await supabase .from('users') .select('*') ```

✅ FIXED CODE – Option 1: Add Domain to CORS Allowlist

In Supabase Dashboard: 1. Go to your project → Settings → API 2. Find "CORS allowed origins" 3. Add: https://myapp.com (production) and http://localhost:3000 (dev) 4. Click "Save"

Then your code works as-is:

```javascript import { createClient } from '@supabase/supabase-js'

const supabase = createClient( 'https://xxx.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' )

const { data, error } = await supabase .from('users') .select('*') // NOW WORKS: myapp.com is whitelisted in Supabase CORS settings ```

✅ FIXED CODE – Option 2: Use RLS with Session Auth (Recommended)

Instead of exposing your anon key, use session-based auth:

```javascript // 1. Client-side login first const { data, error } = await supabase.auth.signInWithPassword({ email: 'user@example.com', password: 'password' })

// 2. Now queries use authenticated session token (not anon key) // CORS still applies, but your session is verified const { data: userData } = await supabase .from('users') .select('*') ```

Pair this with Row Level Security (RLS) policies in Supabase SQL:

```sql ALTER TABLE users ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Users can view own data" ON users FOR SELECT USING (auth.uid() = id); ```

✅ FIXED CODE – Option 3: Use Backend Proxy (Most Secure)

Make requests through your own backend instead:

```javascript // Frontend calls YOUR backend (same origin, no CORS) const response = await fetch('/api/users') const userData = await response.json() ```

```typescript // Your backend (Node/Python/etc) - has private SUPABASE_SERVICE_KEY import { createClient } from '@supabase/supabase-js'

const supabase = createClient( process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_KEY // Private key, never expose to browser )

// Backend queries bypass CORS entirely const { data } = await supabase.from('users').select('*') ```

---

Still Broken? Check These Too

1. Supabase URL mismatch – Verify your createClient() URL matches your actual Supabase project URL (Settings → API → Project URL). Typos here cause silent CORS failures.

2. Anon key has no permissions – Your anon key's RLS policies might deny all reads. Add a policy: CREATE POLICY "anon can read public tables" ON table_name FOR SELECT USING (true);

3. Network request is being preflight blocked – POST/PUT requests require preflight OPTIONS checks. If your CORS origin is set but preflight fails, you may need to update your Supabase plan or contact support for enterprise CORS rules.

4. Browser cache cached the CORS failure – Hard refresh with Cmd+Shift+R (Mac) or Ctrl+Shift+R (Windows) to clear browser cache.

---

Version Note

This guide applies to supabase-js v2.0+ (2024–2026). If you're on v1.x, CORS behavior may differ slightly. Check your package.json version and update if needed: npm install @supabase/supabase-js@latest

---

Learn More

  • [Supabase CORS & Security Best Practices](/?guide=supabase-security)
  • [Row Level Security (RLS) Setup Guide](/?guide=supabase-rls)
  • [Official Supabase CORS Documentation](https://supabase.com/docs/guides/api/cors)
  • ---

    Found a different variation? Drop it in the comments – every 2am production fix helps the next person. 🚀

    🔥 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