Supabase: CORS errors from browser [2026 fix]
Browser blocks requests to Supabase API due to missing CORS headers; add your domain to project settings or use proper client initialization.
Supabase: CORS errors from browser [2026 fix]
TL;DR
Cause: Your browser is blocking requests to Supabase because your domain isn't in the CORS allowlist. Fix: Add your domain to Project Settings → API → CORS or initialize the client with correct credentials.---
Exact Console Error Messages
Here are the real errors you'll see at 2am:
``` Access to XMLHttpRequest at 'https://[project].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 error: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://[project].supabase.co/rest/v1/auth/v1/token (Reason: CORS request did not succeed). ```
``` Fetch error: Failed to fetch at Object.<anonymous> (http://localhost:3000/app.js:45:12) TypeError: Failed to fetch ```
``` Access to fetch at 'https://[project].supabase.co/rest/v1/posts?select=*' from origin 'https://myapp.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be either 'true' or 'false'. ```
``` SubabaseAuthClient: Failed to fetch user: cors error - https://[project].supabase.co/auth/v1/user ```
---
Broken Code vs. Exact Fix
Problem 1: Client initialized without proper CORS config
BROKEN: ```javascript // ❌ This will fail with CORS errors const supabase = createClient( 'https://xyz123.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' );
const { data, error } = await supabase .from('users') .select('*'); ```
FIXED: ```javascript // ✅ Correct initialization with explicit config const supabase = createClient( 'https://xyz123.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', { auth: { autoRefreshToken: true, persistSession: true, detectSessionInUrl: true }, headers: { 'Content-Type': 'application/json' } } );
const { data, error } = await supabase .from('users') .select('*'); ```
Problem 2: Domain not in CORS allowlist
BROKEN: ``` // Your app runs at https://myapp.com // But Supabase dashboard shows: // API CORS Allowlist: (empty or only localhost) ```
FIXED: ``` Steps in Supabase Dashboard: 1. Go to Project Settings → API 2. Find "CORS Allowlist" section 3. Add these entries: - http://localhost:3000 (dev) - https://myapp.com (prod) - https://www.myapp.com (if applicable) 4. Click "Save" 5. Wait 30 seconds for propagation ```
Problem 3: Wrong auth header format
BROKEN: ```javascript // ❌ Sending JWT incorrectly const response = await fetch( 'https://xyz123.supabase.co/rest/v1/users', { headers: { 'Authorization': 'Bearer ' + token // ← Missing 'Bearer' space handling } } ); ```
FIXED: ```javascript // ✅ Use Supabase client (handles headers automatically) const { data, error } = await supabase .from('users') .select('*');
// OR if raw fetch is required:
const response = await fetch(
'https://xyz123.supabase.co/rest/v1/users',
{
method: 'GET',
headers: {
'Authorization': Bearer ${token},
'apikey': 'your_public_anon_key',
'Content-Type': 'application/json'
}
}
);
```
---
Version-Specific Behavior
Note on uncertainty: CORS header handling changed between Supabase JS client v1.x and v2.x. We're referencing v2.x+ (current as of 2026). If you're on v1.x, credentials mode may need { credentials: 'include' } in fetch options—verify your package.json.
---
Still broken? Check these too
1. Environment variables mismatch – Confirm your NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY are exactly correct in .env.local and redeployed. A single typo blocks all requests.
2. Browser extensions blocking requests – Disable ad blockers, privacy extensions (uBlock, Privacy Badger), or corporate proxies. They often strip CORS headers.
3. Trailing slash in domain – Ensure SUPABASE_URL is https://xyz.supabase.co not https://xyz.supabase.co/. Trailing slashes can break preflight requests.
---
Quick Debug Checklist
createClient() from @supabase/supabase-jsCtrl+Shift+R or Cmd+Shift+R)---
Related guides
Official docs: [Supabase CORS Documentation](https://supabase.com/docs/guides/api#cors)
---
Found a different variation? Drop it in the comments.