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 authentication headers.
Supabase CORS Errors from Browser – 2am Fix Guide
TL;DR
Cause: Your browser is blocked from accessing Supabase API because your domain isn't whitelisted in Supabase project settings. Fix: Add your domain to Supabase's CORS allowed origins in Project Settings → API → CORS, or switch to authenticated requests using the Supabase client library.---
Real Console Error Messages
You'll see one of these exact errors:
``` Access to XMLHttpRequest at 'https://[PROJECT_ID].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. ```
``` Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://[PROJECT_ID].supabase.co/rest/v1/posts. (Reason: CORS header 'Access-Control-Allow-Origin' missing). ```
``` Fetch error: TypeError: Failed to fetch Details: No 'Access-Control-Allow-Origin' header is present on the requested resource ```
``` Net::ERR_FAILED 200 (Chrome shows 200 but then blocks the response at browser level) ```
``` Error: Failed to fetch from https://[PROJECT_ID].supabase.co/rest/v1/tables Status: 0 (Indicates CORS preflight failure) ```
---
Broken vs. Fixed Code
❌ BROKEN: Raw fetch without Supabase client
```javascript // This triggers CORS error because domain isn't whitelisted const response = await fetch( 'https://abc123.supabase.co/rest/v1/users', { method: 'GET', headers: { 'apikey': 'YOUR_ANON_KEY' } } ); const data = await response.json(); ```
✅ FIXED: Use Supabase client library (handles CORS automatically)
```javascript // Supabase client sends proper auth headers that bypass CORS issues import { createClient } from '@supabase/supabase-js';
const supabase = createClient( 'https://abc123.supabase.co', 'YOUR_ANON_KEY' );
const { data, error } = await supabase .from('users') .select(); ```
Why this works: The official Supabase client includes proper authentication headers and handles CORS preflights correctly.
---
Alternative Fix: Add domain to CORS whitelist (if you must use raw fetch)
Steps:
1. Log into Supabase Dashboard
2. Go to Project Settings → API
3. Scroll to CORS settings
4. Add your domain:
- Local dev: http://localhost:3000
- Production: https://yourapp.com
- Wildcard (⚠️ not recommended): *
5. Click Save
6. Wait 30 seconds for propagation
Then your fetch works:
```javascript // Now this works because domain is whitelisted const response = await fetch( 'https://abc123.supabase.co/rest/v1/users', { method: 'GET', headers: { 'apikey': 'YOUR_ANON_KEY', 'Content-Type': 'application/json' } } ); ```
---
Still Broken? Check These Too
1. Typo in Project URL or API Key
Verify in Supabase Dashboard → Project Settings → API that you copied the exact URL and anon key. Even one character off causes CORS-like errors.2. Using Service Role Key from Browser
Service role keys must NEVER be exposed in frontend code. They bypass RLS and cause auth failures masquerading as CORS errors. Always useanon key in browser, service role only in backend.3. Browser Cache Still Has Old CORS rejection
Hard refresh:Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac). Then check DevTools → Network tab and confirm Access-Control-Allow-Origin header is present in response.---
Version Note
This guide covers Supabase client v2.0+ (2024-2026). If using v1.x, the behavior is similar but initialization syntax differs. Check your package.json to confirm version. The CORS whitelist approach works across all versions.
---
Quick Reference: When to Use What
| Scenario | Solution |
|----------|----------|
| Using Supabase client library | Nothing—CORS handled automatically |
| Raw fetch from frontend | Add domain to CORS whitelist + use anon key |
| Server-side requests | Use service role key, CORS irrelevant |
| Development localhost | Add http://localhost:PORT to whitelist |
| Production deployment | Add your exact domain (e.g., https://app.com) |
---
Related Guides
---
Official Docs
See [Supabase CORS Configuration](https://supabase.com/docs/guides/api/cors) for the authoritative reference and per-region settings.
---
Found a different variation? Drop it in the comments—2am emergencies need all the solutions we can find.