Supabase: CORS errors from browser [2026 fix]
Browser blocks Supabase API calls due to missing CORS headers. Add your domain to Supabase project settings or use proper auth headers.
Supabase: CORS errors from browser [2026 fix]
TL;DR
Cause: Your browser is blocking requests to Supabase because your domain isn't registered in project settings or you're missing proper authentication headers. Fix: Add your frontend domain to Supabase's CORS allowlist in Project Settings > API > CORS, or ensure requests include theAuthorization header with a valid JWT token.---
Real Console Error Messages
Watch for these exact errors in your browser DevTools Console:
``` Access to XMLHttpRequest at 'https://your-project.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. ```
``` Fetch error: Failed to fetch TypeError: Failed to fetch (anonymous) @ main.js:42 ```
``` No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors'. ```
``` Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be either 'true' or 'false'. ```
``` supabase: error creating user: Error: Failed to sign up user with email. Status 403: Forbidden ```
---
Broken Code vs. Fix
Problem #1: Domain Not in CORS Allowlist
BROKEN: ```javascript // Your frontend at https://myapp.com tries to query Supabase const { data, error } = await supabase .from('users') .select('*') .eq('id', userId); // Returns: CORS policy blocked by browser ```
FIXED: ```javascript // Step 1: Add your domain to Supabase Project Settings // Go to: Project Settings > API > CORS Configuration // Add: https://myapp.com (and http://localhost:3000 for dev)
// Step 2: Your code remains the same - CORS headers now allowed const { data, error } = await supabase .from('users') .select('*') .eq('id', userId); // Now works: browser receives proper Access-Control-Allow-Origin header ```
Problem #2: Missing or Invalid Auth Headers
BROKEN: ```javascript // Using supabase-js client without proper initialization import { createClient } from '@supabase/supabase-js';
const supabase = createClient( 'https://your-project.supabase.co', 'WRONG_KEY_OR_MISSING' );
await supabase.auth.signUp({ email: 'user@example.com', password: 'password123' }); // Request fails: missing valid Authorization header ```
FIXED: ```javascript // Initialize with correct anon key from Supabase import { createClient } from '@supabase/supabase-js';
const supabase = createClient( process.env.VITE_SUPABASE_URL, // https://your-project.supabase.co process.env.VITE_SUPABASE_ANON_KEY // Get from Project Settings > API > Project Keys );
await supabase.auth.signUp({ email: 'user@example.com', password: 'password123' }); // Works: Authorization header automatically included by SDK ```
Problem #3: Direct Fetch Without Headers (Bypassing SDK)
BROKEN: ```javascript // Calling Supabase REST API directly without auth const res = await fetch( 'https://your-project.supabase.co/rest/v1/users', { method: 'GET' } ); // CORS error: missing Authorization and apikey headers ```
FIXED:
```javascript
// Include required headers for direct API calls
const res = await fetch(
'https://your-project.supabase.co/rest/v1/users',
{
method: 'GET',
headers: {
'Authorization': Bearer ${SESSION_JWT_TOKEN},
'apikey': process.env.VITE_SUPABASE_ANON_KEY,
'Content-Type': 'application/json'
}
}
);
// Works: all required CORS headers present
```
---
Still broken? Check these too
1. Environment Variables Not Loaded: Verify your .env.local file exists with VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY. Restart dev server after adding them. Most common at 2am—the key is literally invisible if not loaded.
2. RLS Policies Blocking Requests: Even with CORS fixed, Row Level Security policies might reject your query. Check Project > Authentication > Policies to ensure your policy allows SELECT for your user role.
3. Trailing Slash or URL Mismatch: Ensure Supabase URL in settings exactly matches what you're querying (protocol, domain, no trailing slash). https://proj.supabase.co ≠ https://proj.supabase.co/
---
Quick Action Checklist
Access-Control-Allow-Origin---
Related Guides
---
Official Documentation
[Supabase CORS Configuration](https://supabase.com/docs/guides/api/cors)
---
Found a different variation? Drop it in the comments—CORS errors are environment-specific and your fix might save someone else's 2am emergency.