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:3000 ≠ localhost: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.com ≠ https://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