Supabase: CORS errors from browser [2026 fix]
Browser blocks requests to Supabase due to missing CORS headers; add your domain to Project Settings > API > CORS or use a server proxy.
Supabase: CORS errors from browser [2026 fix]
TL;DR
Cause: Your browser is blocking requests to Supabase because your domain isn't whitelisted in Supabase's CORS settings. Fix: Add your frontend domain to Supabase Project Settings > API > CORS Allow List in under 60 seconds.---
Real Console Error Messages
You'll see one (or more) of these exact errors in your browser console:
``` 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. ```
``` Failed to load resource: the server responded with a status of 400 (Bad Request) No 'Access-Control-Allow-Origin' header is present on the requested resource ```
``` OPTIONS https://[project-id].supabase.co/rest/v1/users 403 CORS policy: Response to preflight request doesn't pass access control check ```
``` {"code":"PGRST107","message":"Could not find the request"} No 'Access-Control-Allow-Origin' header ```
``` TypeError: Failed to fetch at fetch (app.js:42:1) Caused by: TypeError: Failed to fetch at XMLHttpRequest.send ```
---
Broken Code → Fixed Code
❌ BROKEN (No CORS whitelist configured)
```javascript // Your Next.js/React app at http://localhost:3000 import { createClient } from '@supabase/supabase-js';
const supabase = createClient( 'https://your-project.supabase.co', 'your-anon-key' );
// This request gets blocked const { data, error } = await supabase .from('users') .select('*'); ```
Result in browser: CORS 403 error. Supabase server never receives the request—browser stops it at the preflight OPTIONS check.
✅ FIXED (Add domain to CORS Allow List)
Step 1: In Supabase Dashboard
1. Go to Project Settings (bottom left)
2. Navigate to API
3. Find CORS Allow List
4. Add your domain:
- Local dev: http://localhost:3000
- Production: https://yourdomain.com
- Multiple domains: Add each on a new line
5. Click Save
Step 2: Your code stays the same (no changes needed once CORS is fixed)
```javascript // Same code now works const { data, error } = await supabase .from('users') .select('*');
// Browser now allows the request ✓ ```
---
Implementation Details
For Development
``` http://localhost:3000 http://127.0.0.1:3000 http://localhost:3001 ```For Production
``` https://yourdomain.com https://www.yourdomain.com https://api.yourdomain.com ```For Vercel/Netlify Previews
``` https://*.vercel.app https://*.netlify.app ```Note: I'm uncertain about whether wildcard subdomains (*.yourdomain.com) work in all Supabase versions as of 2026—test in your environment and verify in official docs.
---
Still broken? Check these too
1. Wrong Protocol (http vs https)
If your frontend ishttps://yourdomain.com but you whitelisted http://yourdomain.com, CORS will still block it. Match exactly.2. Port Mismatch in Local Dev
You're testing onhttp://localhost:3000 but whitelisted http://localhost:3001. Remove the port from your whitelist to allow any port, or add both explicitly.3. Supabase Client Initialization Issue [related](/?guide=supabase-auth-setup)
If you're using RLS (Row Level Security) policies, CORS headers alone won't help—you also need proper auth tokens. Verify yourcreateClient() is passing valid credentials.4. Network Proxy or CDN Stripping Headers
If you're behind Cloudflare, AWS CloudFront, or corporate proxy, it may strip CORS headers. Bypass it or configure the proxy's CORS settings.5. Browser Cache
Hard refresh:Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac). Browser may have cached the 403 response.---
Alternative: Server-Side Proxy (If CORS Whitelist Fails)
If you can't modify Supabase settings or need extra security:
```javascript
// Next.js API Route: pages/api/users.js
export default async function handler(req, res) {
const response = await fetch(
'https://[project-id].supabase.co/rest/v1/users',
{
headers: {
'Authorization': Bearer ${process.env.SUPABASE_SERVICE_KEY},
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
res.status(200).json(data);
}
```
Then fetch from your own domain: fetch('/api/users') ✓
This bypasses CORS entirely since browser trusts same-origin requests.
---
Official Documentation
[Supabase CORS Configuration Guide](https://supabase.com/docs/guides/api#managing-cors)
[Supabase Project Settings](https://supabase.com/docs/guides/api#api-settings)
---
Quick Checklist
Found a different variation? Drop it in the comments.