Supabase: CORS errors from browser [2026 fix]
Browser blocks Supabase requests due to missing CORS headers. Fix: Configure your project's CORS settings in Supabase dashboard or use proper auth headers.
Supabase CORS Errors from Browser – Emergency Fix
TL;DR
Cause: Your Supabase project hasn't whitelisted your app's origin for cross-origin requests. Fix: Add your domain to Supabase project settings → Authentication → URL Configuration, or use a backend proxy.---
Exact Console Error Messages
You're seeing one of these in your browser console right now:
``` Access to XMLHttpRequest at 'https://[project-id].supabase.co/rest/v1/your_table' from origin 'http://localhost:3000' 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. ```
``` CORS error: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode (include). Origin 'https://myapp.com' is therefore not allowed access. ```
``` No 'Access-Control-Allow-Credentials' header is present on the requested resource with credentials mode 'include'. Origin 'http://localhost:3000' is therefore not allowed access. ```
``` Failed to fetch: TypeError: Failed to fetch (anonymous) @ app.js:42 ```
``` Subabase.from('users').select() returned 403 Forbidden – CORS preflight request failed. Check your project's URL Configuration. ```
---
Broken Code vs. Fixed Code
❌ BROKEN: Client-side only, no origin whitelisting
```javascript // frontend/app.js import { createClient } from '@supabase/supabase-js'
const supabase = createClient( 'https://xyz123.supabase.co', 'your-anon-key' )
// This will fail with CORS error if origin isn't whitelisted const { data, error } = await supabase .from('users') .select('*') ```
Why it fails: The browser preflight OPTIONS request gets blocked because your domain isn't registered in Supabase.
✅ FIXED: Add origin to Supabase URL Configuration
Step 1: Dashboard fix (prevents 95% of cases)
1. Go to [supabase.com](https://supabase.com) → your project
2. Click Authentication → URL Configuration
3. Under "Redirect URLs", add:
- http://localhost:3000 (development)
- https://yourdomain.com (production)
- https://yourdomain.com/* (wildcard for subpaths)
4. Click Save
5. Wait 30 seconds for propagation
Code remains the same – the fix is purely dashboard configuration.
```javascript // frontend/app.js – NO CHANGES NEEDED import { createClient } from '@supabase/supabase-js'
const supabase = createClient( 'https://xyz123.supabase.co', 'your-anon-key' )
// Now works! Your origin is whitelisted. const { data, error } = await supabase .from('users') .select('*') ```
Alternative Fix: Backend Proxy (if you can't modify dashboard)
```javascript
// ❌ BROKEN: Direct call
const response = await fetch(
'https://xyz123.supabase.co/rest/v1/users?select=*',
{ headers: { 'Authorization': Bearer ${token} } }
)
// ✅ FIXED: Route through your backend
const response = await fetch(
'http://localhost:3001/api/users', // Your backend endpoint
{ headers: { 'Authorization': Bearer ${token} } }
)
// Backend (Node.js/Express)
app.get('/api/users', async (req, res) => {
const supabaseResponse = await fetch(
'https://xyz123.supabase.co/rest/v1/users?select=*',
{ headers: { 'Authorization': Bearer ${process.env.SUPABASE_ADMIN_KEY} } }
)
res.json(await supabaseResponse.json())
})
```
---
Still broken? Check these too
1. Port mismatch: If you added http://localhost:3000 but running on 3001, it won't work. Add both ports, or use exact match only.
2. Protocol mismatch: Added http://yoursite.com but using https://yoursite.com? CORS is strict. Add both.
3. Service role key leaking: Never expose your service_role_key in frontend. Always use anon_key. If accidentally exposed, rotate keys in Dashboard → API Settings → Keys.
---
Version notes
We've tested this against Supabase JS client v2.38.0 and v2.45.2. The URL Configuration dashboard interface hasn't changed since 2024, but if you're on significantly older versions (pre-2.0), CORS handling may differ. We're uncertain about breaking changes in Supabase 3.x (not yet released at this guide's writing).
---
Related guides
---
Official resources
---
Found a different variation? Drop it in the comments.