Authentication
Learn about authentication troubles and their solutions.
Start with the first server-side error produced by the failed request. Browser
messages such as Failed to fetch often hide a database, environment or OAuth
configuration error logged by the server.
Sign-up or sign-in fails
Check the shared prerequisites before changing authentication code:
- Confirm the root
.envcontains a validDATABASE_URLand a non-emptyBETTER_AUTH_SECRET. - Apply the committed schema with
npm run db:migrate. - Restart
npm run devafter changing environment variables. - Reproduce the request while watching the terminal that runs Next.js.
Use a unique BETTER_AUTH_SECRET in every deployed environment. Do not copy the
development value from .env.example into production.
Production redirects to localhost
Better Auth receives its baseURL in lib/auth/index.ts. The value comes from
getBaseUrl() in lib/utils.ts in this order:
- A Vercel branch URL for a non-staging Preview deployment.
NEXT_PUBLIC_SITE_URL.- Vercel's generated deployment URL.
http://localhost:3000when none of the values above exist.
Set NEXT_PUBLIC_SITE_URL to the final HTTPS production origin, without a path
or trailing route, then redeploy. Confirm the variable exists in the Production
environment rather than only Development or Preview.
Google OAuth returns a callback error
Verify the configuration as one complete set:
- Set both
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETin the environment where the deployment runs. - Register the exact callback URL
https://yourdomain.com/api/auth/callback/googlein Google Cloud. - Register the matching application origin.
- Keep
enableSocialLoginenabled inconfig/auth.config.tsonly when the credentials are ready. - Confirm
googleremains inlib/auth/oauth-providers.tsxand in thesocialProvidersconfiguration inlib/auth/index.ts.
Google compares callback URLs exactly. Scheme, hostname, port and path must all match. A Vercel branch preview can use a different hostname from production, so register that exact preview callback or test OAuth on a stable staging domain.
Use the OAuth setup guide to generate the callback URL for each environment.
Request rejected because of its origin
config/auth.config.ts builds Better Auth's trusted origins from getBaseUrl(),
the configured site URL and Vercel deployment URLs. If a custom frontend origin
calls the auth API, add that exact HTTPS origin deliberately. Do not use a broad
wildcard for production origins.
After changing trusted origins, restart or redeploy the application and test sign-in, sign-out and an authenticated request from the intended frontend.