Supabase: CORS errors from browser [2026 fix]
Browser blocks Supabase requests due to missing CORS headers. Add your domain to Supabase project settings or use proper auth headers.
Supabase CORS Errors from Browser – Emergency 2am Fix
TL;DR
Cause: Your browser is blocking requests to Supabase because the domain isn't configured in CORS settings or you're missing proper authentication headers. Fix: Add your frontend domain to Supabase project settings under Authentication → URL Configuration, or configure your Supabase client correctly with proper headers.---
Real Console Error Messages
You'll see one or more of these exact errors in your browser console:
``` Access to XMLHttpRequest at 'https://your-project.supabase.co/rest/v1/table_name' 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: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode (include) is 'include'. ```
``` Failed to load resource: the server responded with a status of 401 (Unauthorized) Access to XMLHttpRequest at 'https://your-project.supabase.co/rest/v1/...' from origin 'https://myapp.com' has been blocked by CORS policy. ```
``` TypeError: Failed to fetch (Reason: CORS policy: No 'Access-Control-Allow-Origin' header) ```
``` Syntax error: Unexpected token < in JSON at position 0 (Actually a 403/401 HTML error page, not JSON – CORS blocked it) ```
---
Broken Code vs. Exact Fix
Problem 1: Missing Domain in CORS Configuration
❌ Broken Setup: ```javascript // Your app at https://myapp.com makes requests to Supabase // But myapp.com is NOT added to Supabase allowed origins
const { data, error } = await supabase .from('users') .select('*'); // Result: CORS error in browser ```
✅ Fix: Go to Supabase Dashboard → Your Project → Authentication → URL Configuration
Add these URLs to "Redirect URLs" and "Site URL":
http://localhost:3000 (local dev)https://myapp.com (production)https://www.myapp.com (with www, if applicable)https://*.vercel.app (if using Vercel preview deployments)Then your exact same code works: ```javascript const { data, error } = await supabase .from('users') .select('*'); // ✅ Now works – domain is whitelisted ```
---
Problem 2: Not Using Supabase Client Correctly
❌ Broken (Raw fetch without auth): ```javascript const response = await fetch( 'https://your-project.supabase.co/rest/v1/users?select=*', { method: 'GET' } ); // Missing auth headers + no CORS headers = blocked ```
✅ Fix (Use Supabase client): ```javascript import { createClient } from '@supabase/supabase-js';
const supabase = createClient( 'https://your-project.supabase.co', 'your-public-anon-key' );
const { data, error } = await supabase .from('users') .select('*'); // ✅ Client handles CORS + auth automatically ```
---
Problem 3: RLS Policies Blocking Anonymous Access
❌ Broken (Supabase client configured but RLS denies anonymous): ```javascript const supabase = createClient('...', 'anon-key'); const { data, error } = await supabase .from('users') .select('*'); // Returns: 403 Forbidden – RLS policy requires authentication ```
✅ Fix (Enable public access in RLS or authenticate user): ```javascript // Option A: Disable RLS for this table (dev only!) // In Supabase Dashboard → Table Editor → Click table → "Disable RLS"
// Option B: Create RLS policy allowing public read -- In Supabase SQL Editor: ALTER TABLE users ENABLE ROW LEVEL SECURITY; CREATE POLICY "Allow public read" ON users FOR SELECT TO anon USING (true);
// Option C: Authenticate user first const { error } = await supabase.auth.signInWithPassword({ email: 'user@example.com', password: 'password' }); const { data } = await supabase.from('users').select('*'); // ✅ Authenticated request bypasses anon restrictions ```
---
Still Broken? Check These Too
1. Supabase Service Role Key Exposed in Frontend – Never put service_role_key in browser code. Use only public anon key and authenticate users properly. If you exposed it, regenerate immediately in project settings.
2. Environment Variables Not Loaded – Verify SUPABASE_URL and SUPABASE_ANON_KEY are actually available to your app (check with console.log(process.env.SUPABASE_URL)). Many frameworks require REACT_APP_ or VITE_ prefix.
3. Using Old Supabase Client Version – Upgrade to latest: npm install @supabase/supabase-js@latest. Older versions had inconsistent CORS handling. Note: I'm uncertain if v1 vs v2 client have different CORS defaults in all edge cases – consult [official Supabase changelog](https://github.com/supabase/supabase-js/releases).
---
Related Guides
---
Official Resources
---