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 middleware proxy.
Supabase CORS Errors from Browser – 2am Emergency Fix
TL;DR
Cause: Your Supabase project hasn't whitelisted your app's origin domain in CORS settings. Fix: Add your frontend URL to Supabase project settings under Authentication → URL Configuration, or proxy requests through your own backend.---
Real Console Error Messages
Watch for these exact errors in your browser DevTools (F12 → Console):
``` Access to XMLHttpRequest at 'https://xxxxx.supabase.co/rest/v1/users' 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 policy: No 'Access-Control-Allow-Credentials' header was supplied with the preflight response.
Failed to fetch from Supabase: NetworkError when attempting to fetch resource.
Access to XMLHttpRequest at 'https://xxxxx.supabase.co/auth/v1/token' from origin 'https://myapp.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
PreflightMissing required 'Access-Control-Allow-Methods' header for method POST ```
---
Broken Code vs. Exact Fix
❌ BROKEN (Default Setup)
```javascript // Your React/Vue/Next.js frontend at https://myapp.com import { createClient } from '@supabase/supabase-js'const supabase = createClient( 'https://xxxxx.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' )
// This request fails with CORS error const { data, error } = await supabase .from('users') .select('*') ```
Why it breaks: Supabase server doesn't recognize https://myapp.com as an allowed origin.
✅ FIX #1: Configure URL Allowlist (Recommended)
Step 1: Go to Supabase Dashboard → Your Project → Settings → Authentication → URL Configuration
Step 2: Add these URLs to "Allowed Redirect URLs": ``` http://localhost:3000 https://myapp.com https://www.myapp.com https://staging.myapp.com ```
Step 3: Your code stays identical—CORS headers now work:** ```javascript // Exact same code now works const { data, error } = await supabase .from('users') .select('*') // No errors! Supabase sends proper CORS headers ```
✅ FIX #2: Backend Proxy (For Complex Auth Scenarios)
If you need credential-based requests or have strict CORS requirements:
Broken Frontend:
```javascript
// Cross-origin request with credentials fails
fetch('https://xxxxx.supabase.co/rest/v1/users', {
headers: {
'Authorization': Bearer ${token},
'Content-Type': 'application/json',
},
credentials: 'include' // This + CORS = pain
})
```
Fixed Backend Proxy (Node.js/Express):
```javascript
// Backend at same origin as frontend
app.post('/api/supabase-proxy', async (req, res) => {
const { path, method, body } = req.body
const response = await fetch(https://xxxxx.supabase.co${path}, {
method: method || 'GET',
headers: {
'Authorization': Bearer ${process.env.SUPABASE_SERVICE_KEY},
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
})
res.json(await response.json())
})
```
Fixed Frontend (uses same-origin call): ```javascript // Now calls your backend instead of Supabase directly const { data } = await fetch('/api/supabase-proxy', { method: 'POST', body: JSON.stringify({ path: '/rest/v1/users', method: 'GET', }), }).then(r => r.json()) // No CORS error! Same-origin policy satisfied ```
---
Version-Specific Notes
@supabase/supabase-js v1.x vs v2.x: Both respect CORS headers identically. We're uncertain if Supabase plans changes to CORS handling in 2026+ API versions, but this fix applies to all documented versions through Q4 2025.
Next.js 13+ App Router: Use route handlers (/app/api/supabase-proxy/route.js) instead of Express middleware for the proxy pattern above.
---
Still Broken? Check These Too
1. Cookie/Session Issues – If using supabase.auth.session(), verify session cookies domain matches. Check [auth session handling guide](/?guide=supabase-auth-sessions).
2. Anon Key Permissions – Some tables require RLS (Row Level Security) policies. Even with CORS fixed, queries fail if your anon key lacks permissions. Check Supabase Dashboard → SQL Editor → View RLS policies.
3. Mixed HTTP/HTTPS – Browsers block requests from http://localhost to https://xxxxx.supabase.co. Add http://localhost:3000 explicitly to URL Configuration, or always use HTTPS in production. See [HTTPS enforcement guide](/?guide=cors-https-mixed).
---
Official Resources
📖 Supabase CORS Documentation: https://supabase.com/docs/guides/api/cors 📖 Authentication URL Configuration: https://supabase.com/docs/guides/auth/managing-user-data#url-configuration
---
Found a different variation? Drop it in the comments—include your error message, framework, and Supabase version so we keep this guide current.