Supabase: CORS errors from browser [2026 fix]
Browser blocks your Supabase API calls due to missing CORS headers. Fix: Add your domain to Supabase project settings or configure proper origin headers.
Supabase CORS Errors from Browser: 2am Production Fix
TL;DR
Cause: Your browser domain isn't authorized in Supabase's CORS allowlist, so the browser blocks cross-origin requests to your Supabase instance. Fix: Add your production domain to Supabase project settings → Authentication → URL Configuration → Authorized redirect URLs, OR configure your client to send correct origin headers.---
Exact Console Error Messages
You'll see one of these in your browser console:
``` Access to XMLHttpRequest at 'https://xyzabc.supabase.co/auth/v1/user' from origin 'https://yourdomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. ```
``` CORS error: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xyzabc.supabase.co/rest/v1/. (Reason: CORS header 'Access-Control-Allow-Origin' missing). Status code: (null). ```
``` Fetch error: Failed to fetch TypeError: Failed to fetch at async getUser (auth.js:42:15) ```
``` No 'Access-Control-Allow-Credentials' header in the response when credentials mode is 'include', origin is 'https://staging.yourdomain.com' is therefore not allowed access to the resource at 'https://xyzabc.supabase.co/auth/v1/signup'. ```
``` [WARN] Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://project.supabase.co/rest/v1/profiles. Reason: Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'. ```
---
Broken Code vs. Exact Fix
Problem 1: Missing Authorized Redirect URLs
BROKEN: ```javascript // Your Supabase client works locally but fails in production const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: 'https://yourdomain.com/auth/callback', // ← Not in allowlist }, }); ```
FIXED: ```javascript // Step 1: Go to Supabase Dashboard → Authentication → URL Configuration // Step 2: Add these under "Authorized redirect URLs": // - https://yourdomain.com/auth/callback // - https://yourdomain.com // - http://localhost:3000 (for dev) // Step 3: Code stays the same, but now works!
const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: 'https://yourdomain.com/auth/callback', // ← Now authorized }, }); ```
Problem 2: REST API Calls Without Proper Headers
BROKEN:
```typescript
// Direct fetch calls get blocked
const response = await fetch(
'https://xyzabc.supabase.co/rest/v1/profiles',
{
method: 'GET',
headers: {
'Authorization': Bearer ${token},
// Missing apikey or origin handling
},
}
);
```
FIXED: ```typescript // Use Supabase client instead (handles CORS automatically) import { createClient } from '@supabase/supabase-js';
const supabase = createClient( 'https://xyzabc.supabase.co', 'your-anon-key', // Use your public anon key { auth: { persistSession: true, autoRefreshToken: true, }, } );
// This automatically includes correct CORS headers const { data, error } = await supabase .from('profiles') .select('*'); ```
Problem 3: Production Domain Not in Allowlist
BROKEN: ```env
.env.local works fine, but production fails
VITE_SUPABASE_URL=https://xyzabc.supabase.co VITE_SUPABASE_ANON_KEY=eyJhbGc...No domain configuration in Supabase settings
```FIXED: ```env
Keep your environment variables the same
VITE_SUPABASE_URL=https://xyzabc.supabase.co VITE_SUPABASE_ANON_KEY=eyJhbGc...Then in Supabase Dashboard:
Authentication → URL Configuration → Authorized redirect URLs:
https://yourdomain.com
https://www.yourdomain.com
https://api.yourdomain.com (if different subdomain)
https://staging.yourdomain.com (for staging)
```Note: *I'm uncertain whether Supabase versions before 2024 required additional JWT secret configuration for CORS—if you're on an older instance, check your project's API settings for deprecated CORS configuration options.*
---
Still Broken? Check These Too
1. Wrong Supabase URL: Verify you're using the exact URL from your Supabase project settings (Settings → API → URL). Copy-paste errors cause silent CORS failures.
2. Credentials mode mismatch: If using credentials: 'include' in fetch, ensure your Supabase client is initialized with the same mode. Use Supabase's official client library instead of raw fetch when possible—it handles this automatically.
3. Wildcard origin with credentials: If you see "Credential is not supported if CORS header is '*'", you're mixing cookie-based auth with unrestricted origins. Either remove credentials: 'include' or add specific domains to the allowlist instead of using wildcards.
---
Quick Checklist
createClient() from @supabase/supabase-js, not raw fetcheyJ), not service key---
[Related: Supabase Auth Setup Guide](/?guide=supabase-auth) [Related: JWT Token Errors Fix](/?guide=jwt-errors) [Official Supabase CORS Docs](https://supabase.com/docs/guides/api/cors)
---
Found a different variation? Drop it in the comments.