CORS & cookies
CORS preflight failures
Symptoms: browser console shows Access to fetch ... blocked by CORS policy. The request never reaches the server.
The marketplace CORS config:
app.enableCors({
origin: config.frontendUrl.split(',').map(s => s.trim()),
credentials: true,
});
Steps:
- Verify
FRONTEND_URLmatches your origin exactly.http://localhost:8080≠http://localhost:8081.https://app.fleapo.ai≠https://www.app.fleapo.ai. - Make sure you're not using
*.credentials: trueplus wildcard origin is forbidden by every modern browser. CORS preflight will fail silently. - For multiple frontends, comma-separate:
FRONTEND_URL=https://marketplace.fleapo.ai,https://staging.marketplace.fleapo.ai. The middleware splits and trims.
Restart the backend after any CORS env change.
Cookies not being sent
Symptoms: backend says "not signed in" even though you just signed in.
credentials: 'include'must be on every fetch. The generated client handles this; if you write a raw fetch, add it.- Cookie attributes:
- Same-origin →
SameSite=Laxis fine. - Cross-origin → MUST be
SameSite=None; Secure.Securerequires HTTPS (localhost is exempt in modern Chrome).
- Same-origin →
- HttpOnly is fine — cookies still travel cross-origin if SameSite allows.
- Domain attribute — better-auth uses the default (same as request host). Don't override.
"Cookie set but not stored"
DevTools → Network → response → Set-Cookie header should be present. Application → Cookies should show it after the response.
If the header is there but the cookie isn't stored:
- Wrong
Domainattribute. SameSite=Strictblocking cross-site.Secureset but request was HTTP.
"Cookie stored but not sent"
DevTools → Application → Cookies confirms it's stored. Network shows the next request doesn't include it.
- Cross-origin? Check
SameSite. - Subdomain mismatch?
app.example.comcookie won't be sent toapi.other.com. - Browser extension blocking it? Test in incognito.
"401 on /api/auth/get-session after redirect"
Classic OAuth callback scenario. The browser redirected from marketplace → agent backend. Agent backend's response set a session cookie, but the next request from the agent frontend doesn't include it.
- Agent backend's cookie config must be
SameSite=None; Securebecause the frontend (app.my-agent.com) and backend (api.my-agent.com) are cross-origin. - Both must be HTTPS in production.
Local HTTPS for testing
When testing cross-origin with SameSite=None locally:
- Modern Chrome accepts
Securecookies onlocalhost. Other browsers may not. - Use
mkcertto issue local certs if needed. - Or use Cloudflare Tunnel / ngrok to expose with HTTPS.
Wildcard subdomains
If you want every *.preview.example.com to be allowed, the marketplace doesn't support that out of the box. Options:
- Add each preview origin explicitly (tedious).
- Or modify the CORS config to use a regex predicate. Note that you'll lose the simple
FRONTEND_URLenv-var contract.
Debugging tool
curl with verbose:
curl -v -b cookies.txt -H "Origin: http://localhost:8080" \
http://localhost:3000/api/auth/get-session
Inspect Access-Control-Allow-Origin, Access-Control-Allow-Credentials headers in the response.