All guidesMore providers: databases, auth, hosting, email and payments
On this page

Better Auth error

Better Auth

You are using the default secret. Please set BETTER_AUTH_SECRET in your environment variables or pass secret in your auth config.

By Ohad Krispin, founder of VibeRaven · LinkedIn

"You are using the default secret. Please set BETTER_AUTH_SECRET in your environment variables or pass secret in your auth config." is a BetterAuthError thrown when no secret reached Better Auth and NODE_ENV is production. With no secret option, no BETTER_AUTH_SECRET and no AUTH_SECRET, it falls back to a built-in placeholder, and in production it refuses to run on that. Locally nothing complains, because next dev runs with NODE_ENV=development. Generate a value with openssl rand -base64 32, add BETTER_AUTH_SECRET in Vercel for Production and Preview, and redeploy, because Vercel applies changed variables only to new deployments. Reproduced with better-auth 1.7.14 on 2026-10-31.

What does Better Auth do when no secret is set?

The secret option falls back to the BETTER_AUTH_SECRET variable and then AUTH_SECRET. The options reference says that with none of them set it uses a placeholder value and, in production, throws an error. The check is in createAuthContext (context/create-context.ts): it compares the secret with the placeholder when NODE_ENV is production. In a run on 2026-10-31 with no secret and NODE_ENV=production, the request to the handler threw the message below (the real message wraps BETTER_AUTH_SECRET and secret in backticks). With NODE_ENV=development, or with it unset, the same request answered 200 and logged no error.

BetterAuthError: You are using the default secret. Please set BETTER_AUTH_SECRET in your environment variables or pass secret in your auth config.

Why does it work locally and fail on Vercel?

The Next.js docs say NODE_ENV is development for next dev and production for every other command, so next build and next start run the production check. The same docs say create-next-app adds all .env files to .gitignore, so a secret kept in .env or .env.local stays on your machine and Vercel never sees it. On Vercel a variable applies to the environments you selected when you added it (Production, Preview, Development), and a change reaches only new deployments. With no secret set, development runs on the placeholder without a word, so the gap shows up on the first production deploy.

How long should BETTER_AUTH_SECRET be?

The installation docs say at least 32 characters, generated with high entropy, and suggest openssl rand -base64 32. The source only logs warnings for a value under 32 characters or one that looks low-entropy; the only thing that throws is the placeholder in production. A short value logs a warning and does not throw.

openssl rand -base64 32

Checklist

How to fix it, then check the fix

  1. 01
    Find where the app reads the secret, including committed .env files:
    grep -rnE "BETTER_AUTH_SECRET|AUTH_SECRET|secret:" --exclude-dir=node_modules --exclude-dir=.next .
  2. 02
    Generate a value and add it in Vercel for each environment that runs sign-in:
    openssl rand -base64 32
    vercel env add BETTER_AUTH_SECRET production
    vercel env add BETTER_AUTH_SECRET preview
  3. 03If the config passes secret: process.env.SOME_NAME, set that name in Vercel too, or delete the option and let Better Auth read BETTER_AUTH_SECRET.
  4. 04Add BETTER_AUTH_SECRET= with no value to .env.example, so the name is documented without the secret.
  5. 05Redeploy, then open /api/auth/get-session on the deployment: it answers 200 (null when signed out), not an error.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Can I use AUTH_SECRET instead?

Yes. The options reference lists process.env.AUTH_SECRET next to process.env.BETTER_AUTH_SECRET, so an app moved over from Auth.js can keep the name it has. Better Auth's installation docs and messages use BETTER_AUTH_SECRET.

How do I rotate the secret later?

Better Auth documents a secrets option, also read from the BETTER_AUTH_SECRETS variable, for rotation without breaking data the old secret encrypted. When secrets is set, the single secret option is used only as a fallback for decrypting legacy data. Read the options reference before you replace a secret on a live app.