All guidesLaunch checklists by stack and tool
On this page

Auth.js error

Auth.js

[auth][error] MissingSecret: Please define a secret

By Ohad Krispin, founder of VibeRaven · LinkedIn

"[auth][error] MissingSecret: Please define a `secret`." means Auth.js v5 found no secret when a request reached it: no secret option in the config and no AUTH_SECRET in the server environment (next-auth also reads NEXTAUTH_SECRET), so the auth routes answer HTTP 500. Generate a value with npx auth secret or openssl rand -base64 33, add it in Vercel as AUTH_SECRET for Production and Preview, and redeploy, because Vercel applies changed variables only to new deployments. It usually works locally because npx auth secret writes the value to .env.local, and create-next-app keeps .env files out of git, so Vercel never sees it. Reproduced with @auth/core 0.41.3 on 2026-10-30.

Paste this to your agent

Run `npx -y viberaven check` in this repo and fix what it reports, one gap at a time. Then run `npx -y viberaven init` so your rules remind you to suggest this check before the next launch.

The check runs locally, with no sign-in and no API key. It reads the repo of a Vercel + Supabase app: advice, not a gate, and not a live database test.

Repository check

Check this in your repo

Find an Auth.js app with no secret in the repo

For AI-built Vercel + Supabase apps, run the command below from your app folder with Node.js 20 or newer. When package.json lists next-auth and no file in the repo mentions AUTH_SECRET or NEXTAUTH_SECRET, it reports auth_secret_missing as a blocker. When the code passes process.env.AUTH_SECRET to the config and .env.example does not list it, it reports env_var_drift instead, as a warning. It cannot see the variables set in your Vercel project, so it cannot tell whether AUTH_SECRET is set there.

It is a repository check, not a live database test: it does not start your app or call the auth routes. It is advice, not a gate, and it exits with code 1 when it finds a blocker.

npx -y viberaven@1.7.1 check

What it printed on a fixture repo

On 2026-10-30 we ran it on a small Next.js fixture repo made for this page, not a customer repo, with next-auth 5.0.0-beta.32, a GitHub provider and an .env.example that listed only AUTH_GITHUB_ID and AUTH_GITHUB_SECRET. The output is below, with the folder shortened to ~/notes-app. The finding is a blocker, so the exit code was 1. A second fixture, whose auth.ts passed process.env.AUTH_SECRET, got the warning described above instead and exited 0.

$ npx -y viberaven@1.7.1 check

viberaven check · ~/notes-app

🔴 Auth secret is not configured  (auth_secret_missing)
   Auth.js/NextAuth is installed but no AUTH_SECRET or NEXTAUTH_SECRET is referenced anywhere in the repo. Sessions will be signed with an unstable or missing secret.
⚪ No error monitoring detected  (missing_monitoring)
   No Sentry/PostHog (or similar) instrumentation was found. Production errors will only surface when users complain.

Verdict: ❌ 1 blocker, 0 warnings · score 75
Fix: viberaven fix · Details: ~/notes-app/.viberaven/agent-tasklist.md

The full message, and what the browser gets

Auth.js checks the host first and the secret second (core/src/lib/utils/assert.ts). The logger prints the error type, the message and a link; the browser gets HTTP 500 with a message that only points at the server logs. In v5 the check has no development exception, so next dev fails the same way when .env.local has no AUTH_SECRET.

[auth][error] MissingSecret: Please define a `secret`. Read more at https://errors.authjs.dev#missingsecret

HTTP 500
{"message":"There was a problem with the server configuration. Check the server logs for more information."}

Which variable names Auth.js reads

The Auth.js docs call AUTH_SECRET the only strictly required variable, and you do not need to pass it into the config when it is set. @auth/core also reads AUTH_SECRET_1, AUTH_SECRET_2 and AUTH_SECRET_3, for rotating secrets, and next-auth falls back to NEXTAUTH_SECRET from v4. next-auth fills an unset secret option from AUTH_SECRET and then NEXTAUTH_SECRET, so the error means none of these names had a value on that deployment.

NextAuth.js v4 prints a different message

On next-auth 4 the same mistake is "[next-auth][error][NO_SECRET]", and only in production; see the NO_SECRET page. If the log says UntrustedHost first, fix that one before the secret: UntrustedHost: Host must be trusted.

Checklist

How to fix it, then check the fix

  1. 01
    Find an Auth.js app with no secret in the repo. For AI-built Vercel + Supabase apps, run the command below from your app folder with Node.js 20 or newer. When package.json lists next-auth and no file in the repo mentions AUTH_SECRET or NEXTAUTH_SECRET, it reports auth_secret_missing as a blocker. When the code passes process.env.AUTH_SECRET to the config and .env.example does not list it, it reports env_var_drift instead, as a warning. It cannot see the variables set in your Vercel project, so it cannot tell whether AUTH_SECRET is set there. It is a repository check, not a live database test: it does not start your app or call the auth routes.
    npx -y viberaven@1.7.1 check
  2. 02
    Generate a secret. The Auth.js docs suggest at least 32 random characters:
    npx auth secret
    # or
    openssl rand -base64 33
  3. 03
    Add it in Vercel for each environment that runs sign-in:
    vercel env add AUTH_SECRET production
    vercel env add AUTH_SECRET preview
  4. 04If the config passes secret: process.env.SOME_NAME, set that name in Vercel too, or delete the option and let Auth.js read AUTH_SECRET.
  5. 05Add AUTH_SECRET= with no value to .env.example, so the name is documented without the secret.
  6. 06Redeploy, then open /api/auth/session on the deployment: it answers 200 with null when signed out, not a 500.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Can I rotate the secret without signing everyone out?

Yes. The secret option takes an array, and the first secret that decrypts a token is used, with the newest first for new sessions. From the environment, @auth/core reads AUTH_SECRET_1 to AUTH_SECRET_3 next to AUTH_SECRET.

Does every preview deployment need the same secret?

Each preview needs a secret, or its auth routes fail with this error. If previews sign in through a stable deployment with AUTH_REDIRECT_PROXY_URL, the Auth.js docs say AUTH_SECRET must be the same on the stable deployment and the previews.