Supabase: CORS errors from browser [2026 fix]

Browser blocks Supabase API calls due to missing CORS headers. Fix: Add your domain to Supabase project settings or configure proper headers.

Supabase CORS Errors from Browser – Production Fix

TL;DR

Cause: Supabase API rejects your browser's origin because it's not whitelisted in your project settings. Fix: Add your domain to Supabase dashboard → Project Settings → API → CORS Allowed Origins, or proxy requests through your own backend.

---

Exact Error Messages You'll See

``` 1. Access to XMLHttpRequest at 'https://[project].supabase.co/rest/v1/users' from origin 'https://yourdomain.com' 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.

2. TypeError: Failed to fetch POST https://[project].supabase.co/rest/v1/posts 403 Access-Control-Allow-Origin: missing

3. CORS policy: 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'.

4. No 'Access-Control-Allow-Methods' header is present on the requested resource. Requested method: OPTIONS

5. Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://[project].supabase.co/rest/v1/. (Reason: CORS header 'Access-Control-Allow-Origin' missing). ```

---

Broken Code vs. Fixed Code

❌ BROKEN: Direct browser request without whitelisting

```javascript // This fails because yourdomain.com isn't in Supabase CORS settings const { data, error } = await supabase .from('users') .select('*') .eq('id', userId);

if (error) console.error('CORS Error:', error); ```

✅ FIX #1: Add domain to Supabase CORS whitelist (Recommended for SPAs)

Step 1: Go to [Supabase Dashboard](https://app.supabase.com) → Select Project → Settings → API

Step 2: Locate "CORS Allowed Origins" field

Step 3: Add your domains (one per line): ``` https://yourdomain.com https://www.yourdomain.com https://app.yourdomain.com http://localhost:3000 ```

Step 4: Your existing code now works:**

```javascript // Same code, now CORS passes because domain is whitelisted const { data, error } = await supabase .from('users') .select('*') .eq('id', userId);

if (error) console.error('Error:', error); // ✅ Works at 2am without CORS blocking ```

✅ FIX #2: Proxy through your backend (More secure)

Frontend (no direct Supabase calls): ```javascript // Call YOUR backend instead const response = await fetch('/api/users/' + userId); const { data, error } = await response.json(); ```

Backend (Node/Express example): ```javascript const express = require('express'); const { createClient } = require('@supabase/supabase-js');

const supabase = createClient(SUPABASE_URL, SUPABASE_KEY); const app = express();

app.get('/api/users/:id', async (req, res) => { // Server-to-server call – CORS doesn't apply const { data, error } = await supabase .from('users') .select('*') .eq('id', req.params.id) .single();

if (error) return res.status(400).json({ error }); res.json({ data }); }); ```

✅ FIX #3: Use service role key with anonymous key separation

```javascript // In browser: use ANON key (limited permissions) const supabase = createClient( import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_ANON_KEY // Publicly safe );

// In backend: use SERVICE_ROLE_KEY (full permissions) const supabase = createClient( process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY // Never in browser ); ```

---

Version-Specific Notes

Supabase JS SDK v2.x: CORS handling identical to v1.x for REST API calls. If you're uncertain whether your SDK version supports a specific CORS config option, check the [official SDK changelog](https://github.com/supabase/supabase-js/releases).

Supabase hosted (supabase.co domain): CORS enforcement has been consistent since 2023. Self-hosted Supabase instances may have different CORS defaults—consult your instance admin.

---

Still Broken? Check These Too

1. Wildcard domains don't work: Supabase doesn't accept * or *.yourdomain.com. You must whitelist exact origins: https://app.yourdomain.com, https://yourdomain.com, etc. separately.

2. Protocol mismatch: http://localhost:3000 ≠ https://localhost:3000. Ensure your CORS entry matches your exact browser URL (check address bar).

3. RLS policies blocking preflight: Even with CORS fixed, Row-Level Security (RLS) policies on your table can cause 403 errors. Verify your table's RLS policies allow the anon key to perform select, insert, or update as needed. See [RLS troubleshooting guide](/?guide=supabase-rls-errors).

4. Stale browser cache: CORS preflight responses are cached. Clear browser cache (Ctrl+Shift+Del) and hard-refresh (Ctrl+F5) after updating CORS settings.

5. Custom headers without preflight: If sending custom headers, browser sends OPTIONS preflight. Supabase must allow OPTIONS method. This is automatic if CORS is configured correctly.

---

Resources

  • [Supabase CORS Configuration Docs](https://supabase.com/docs/guides/api/cors)
  • [Related: Supabase Auth Errors](/?guide=supabase-auth-errors)
  • [Related: Edge Function CORS Setup](/?guide=edge-function-cors)
  • ---

    Found a different variation? Drop it in the comments – CORS failures can be tricky with redirects, proxies, and subdomains. Your 2am fix might help someone else.

    🔥 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