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 Allowed Origins.

Supabase: CORS errors from browser [2026 fix]

TL;DR

Cause: Your browser is blocking requests to Supabase because your app's domain isn't in the CORS allowed origins list.

Fix: Add your domain to Supabase Project Settings > API > CORS Allowed Origins (include https:// and exact domain/port).

---

Real Console Error Messages

You'll see one of these 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-Origin' header in the response must not be the wildcard '*' when the request's credentials mode ('include') is 'include'. ```

``` 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'. ```

``` The CORS protocol does not allow specifying a wildcard ('*') for the header 'Access-Control-Allow-Credentials' when the 'Access-Control-Allow-Origin' header is '*'. ```

``` Failed to fetch user session from https://your-project.supabase.co/auth/v1/user: No 'Access-Control-Allow-Origin' header is present on the requested resource. ```

---

Broken Code vs. Fixed Code

Scenario 1: Missing CORS Configuration (Most Common)

Broken: ```javascript // Your React/Vue/Svelte app running at http://localhost:3000 import { createClient } from '@supabase/supabase-js';

const supabase = createClient( 'https://your-project.supabase.co', 'your-public-anon-key' );

const { data, error } = await supabase .from('posts') .select('*'); // CORS error thrown here ↑ ```

Fixed (in Supabase Dashboard): 1. Go to Project Settings (gear icon) 2. Click "API" in left sidebar 3. Scroll to "CORS Allowed Origins" 4. Click "Add origin" and enter: http://localhost:3000 5. For production, add: https://yourdomain.com (without trailing slash) 6. Save

Your code stays the same—the fix is purely configuration.

Scenario 2: Localhost + Port Mismatch

Broken: ```javascript // App running on http://localhost:3000 // But CORS only has http://localhost added (without :3000) const supabase = createClient(...); await supabase.from('users').select(); // Still CORS error ```

Fixed: Add BOTH of these as separate origins in Supabase:

  • http://localhost:3000
  • http://localhost:5173 (if you use Vite)
  • http://localhost:8000 (if you use different ports for testing)
  • Note: Exact port matters. localhost:3000localhost:3001.

    Scenario 3: Development vs. Production Domain

    Broken: ```javascript // Works locally with http://localhost:3000 // Deployed to https://myapp.vercel.app // But CORS only has localhost, not your Vercel domain await supabase.from('data').select(); // CORS error in production ```

    Fixed: Add all these origins: ``` http://localhost:3000 https://myapp.vercel.app https://www.myapp.vercel.app (if applicable) ```

    ---

    Still Broken? Check These Too

    1. Using wildcard * with credentials – If you need to send cookies/auth tokens, you cannot use *. List explicit domains instead. We're uncertain if Supabase auto-rejects * with credentials in v2026 or silently fails; test both approaches.

    2. Trailing slashes and protocols – Ensure you use https:// for production. yourdomain.comhttps://yourdomain.com. Check [CORS authentication best practices](/?guide=cors-auth).

    3. Browser cache & Service Workers – Clear browser cache (Ctrl+Shift+Delete), disable service workers in DevTools, or do a hard refresh (Ctrl+Shift+R). Old CORS responses get cached.

    4. Supabase-js client version – Ancient versions (<2.0) had different CORS behavior. Update: npm install @supabase/supabase-js@latest. See our [Supabase client version guide](/?guide=supabase-versions) for migration steps.

    5. Using direct fetch instead of SDK – If you're calling /rest/v1/ endpoints with raw fetch() instead of the JS client, ensure you include the apikey header:

    ```javascript // Raw fetch approach const response = await fetch( 'https://your-project.supabase.co/rest/v1/posts', { headers: { 'apikey': 'your-public-anon-key', 'Content-Type': 'application/json' } } ); ```

    ---

    Key Takeaways

  • CORS is enforced by browsers only, not your server
  • Supabase CORS rules are project-wide and apply to all Origins
  • Subdomain, port, and protocol must match exactly
  • localhost during dev, full domain during prod
  • ---

    Official Resources

  • [Supabase CORS Configuration Docs](https://supabase.com/docs/guides/auth/managing-sign-up-and-invitations#verify-email-addresses)
  • [MDN: CORS Guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
  • ---

    Found a different variation? Drop it in the comments—community fixes help everyone at 2am.

    🔥 0d
    LIVE
    PlanetScale rage spiking Vercel pricing complaints Railway gaining fast Supabase happiness rising Resend loved by devs PlanetScale rage spiking Vercel pricing complaints Railway gaining fast Supabase happiness rising
    DEVELOPER PAIN RADAR // Loading...

    Developers complain.
    Opportunities appear.

    We track what developers are struggling with today — and what opportunities that creates.

    guides today
    avg happiness
    🔥 Pain
    📖 Guides
    🔭 Explore
    👤 Mine
    🔥 Pain Radar — rage scores today
    ↗ share
    💡 Opportunity Feed — pain = market gap
    📈 Tool Momentum
    all scores →
    📖 Latest Guide
    all guides →
    📖 All Guides
    📊 Tool Scores
    + Submit
    📰 Hacker News
    ➕ Submit a Tool
    ← back