NextAuth callback or CSRF mismatch
Applies to: core
Symptom
Signing in redirects you away from the app, or login silently fails with one of:
http://localhost:3001/api/auth/signin?error=Callback
[next-auth][error][CLIENT_FETCH_ERROR] fetch failed — Invalid URL
[next-auth][error][CSRF_TOKEN_MISMATCH]You see the sign-in form submit, then land on a page that looks like the login screen again with no error banner.
Likely cause
NextAuthNextAuthThe auth library HiveCFM Core uses to handle sessions, OAuth providers, and credentials. reads NEXTAUTH_URL at boot and uses it to build every callback URL it hands to providers and every cookie scope. If that value disagrees with the origin the browser actually uses, the callback lands on the wrong host, the CSRF cookie is scoped to the wrong origin, or the session token is rejected.
Typical mismatches:
- Running native dev on
http://localhost:3000but.env.localstill saysNEXTAUTH_URL=http://localhost:3001. - Running the Docker stack on
http://localhost:3001but.envstill saysNEXTAUTH_URL=http://localhost:3000. - Behind an SSH tunnel on a different host, or behind a reverse proxy that changes the origin, with
NEXTAUTH_URLstill pointing atlocalhost.
The JWTJWTA compact, signed token that carries identity between services. HiveCFM issues one per authenticated user./session callback code lives in hivecfm-core/apps/web/app/api/auth/[...nextauth]/route.ts and logs failures through @hivecfm/logger — check those logs for specifics.
Fix
Confirm the URL the browser is actually using
Open DevTools → Network and look at the first request for /api/auth/*. The origin you see there is the value NEXTAUTH_URL must match exactly — same scheme, same host, same port, no trailing slash.
Set NEXTAUTH_URL to match
Edit the env file that the server is reading:
# Docker stack (server reads hivecfm-core/.env)
NEXTAUTH_URL=http://localhost:3001
WEBAPP_URL=http://localhost:3001# Native dev (server reads hivecfm-core/.env.local, which overrides .env)
NEXTAUTH_URL=http://localhost:3000
WEBAPP_URL=http://localhost:3000Keep NEXTAUTH_URL and WEBAPP_URL aligned — HiveCFM builds outbound links from WEBAPP_URL.
Restart the server
NextAuth reads NEXTAUTH_URL once at startup, so an edit without a restart changes nothing:
# Docker
docker compose restart hivecfm-core
# Native dev
# Ctrl+C pnpm dev, then:
pnpm --filter @hivecfm/web devClear the stale auth cookies
Old cookies scoped to the wrong origin will keep triggering CSRF errors. In DevTools → Application → Cookies, delete everything for the origin you are testing on (or open a private window).
Verify
- Sign in completes and lands on the authenticated dashboard without bouncing back to
/signin. curl -s http://localhost:3001/api/auth/csrfreturns a JSON{ "csrfToken": "..." }at the same origin you intend to use.- No
CLIENT_FETCH_ERRORorCSRF_TOKEN_MISMATCHentries in the server logs on login.
Prevent
- Treat
NEXTAUTH_URLas part of the port decision — if you changeHIVECFM_PORT, updateNEXTAUTH_URLandWEBAPP_URLin the same edit. - When tunnelling through SSH or a reverse proxy, set
NEXTAUTH_URLto the external URL the browser will actually hit — notlocalhost. - Never commit a production
NEXTAUTH_URLinto a dev.env.local; copy from.env.exampleinstead.