[GH-ISSUE #8469] getCookieCache does not fall back to DEFAULT_SECRET in non-production environments #19730

Closed
opened 2026-04-15 19:03:25 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @turisanapo on GitHub (Mar 7, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/8469

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Configure betterAuth() with session: { cookieCache: { enabled: true } } and no secret option or BETTER_AUTH_SECRET env var (relying on the dev default)
  2. Use getCookieCache() from better-auth/cookies in a separate middleware (e.g., Elysia, Hono, Express) to validate the cached session cookie
  3. Send a request with a session cookie — getCookieCache throws:

    "getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable"

Current vs. Expected behavior

betterAuth() silently falls back to DEFAULT_SECRET ("better-auth-secret-12345678901234567890") in non-production environments when no secret is configured (create-context.mjs, line 80). This allows zero-config local development.

However, getCookieCache() (cookies/index.mjs, line 204-205) does not use this same fallback. It only checks config?.secret || env.BETTER_AUTH_SECRET, and throws a hard error if neither is set.

This means the auth server starts and signs cookies successfully using the default secret, but getCookieCache — the recommended way to read those cookies in middleware — cannot verify them without the developer explicitly passing the secret.

Expected: getCookieCache should fall back to DEFAULT_SECRET in non-production environments, consistent with how betterAuth() itself resolves the secret.

What version of Better Auth are you using?

1.5.3

Which area(s) are affected? (Select all that apply)

Backend, Documentation

Auth config (if applicable)

import { betterAuth } from "better-auth";

export const auth = betterAuth({
  // No `secret` — relying on default in dev
  session: {
    cookieCache: { enabled: true },
  },
});

Middleware consuming the cookie:

import { getCookieCache } from "better-auth/cookies";

// This throws in dev when no secret is provided,
// even though the server above works fine without one
const session = await getCookieCache(request, {
  // secret: ???  — not available without explicit config
});

Additional context

The workaround is to always set the secret explicitly (or set BETTER_AUTH_SECRET), but this breaks the zero-config DX that betterAuth() provides for local development. A simple fix would be to import DEFAULT_SECRET in getCookieCache and use it as a fallback when process.env.NODE_ENV !== "production", matching the server's behavior.

Originally created by @turisanapo on GitHub (Mar 7, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/8469 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Configure `betterAuth()` with `session: { cookieCache: { enabled: true } }` and **no** `secret` option or `BETTER_AUTH_SECRET` env var (relying on the dev default) 2. Use `getCookieCache()` from `better-auth/cookies` in a separate middleware (e.g., Elysia, Hono, Express) to validate the cached session cookie 3. Send a request with a session cookie — `getCookieCache` throws: > `"getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable"` ### Current vs. Expected behavior `betterAuth()` silently falls back to `DEFAULT_SECRET` (`"better-auth-secret-12345678901234567890"`) in non-production environments when no secret is configured (`create-context.mjs`, line 80). This allows zero-config local development. However, `getCookieCache()` (`cookies/index.mjs`, line 204-205) does **not** use this same fallback. It only checks `config?.secret || env.BETTER_AUTH_SECRET`, and throws a hard error if neither is set. This means the auth server starts and signs cookies successfully using the default secret, but `getCookieCache` — the recommended way to read those cookies in middleware — cannot verify them without the developer explicitly passing the secret. **Expected:** `getCookieCache` should fall back to `DEFAULT_SECRET` in non-production environments, consistent with how `betterAuth()` itself resolves the secret. ### What version of Better Auth are you using? 1.5.3 ### Which area(s) are affected? (Select all that apply) Backend, Documentation ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; export const auth = betterAuth({ // No `secret` — relying on default in dev session: { cookieCache: { enabled: true }, }, }); ``` Middleware consuming the cookie: ```typescript import { getCookieCache } from "better-auth/cookies"; // This throws in dev when no secret is provided, // even though the server above works fine without one const session = await getCookieCache(request, { // secret: ??? — not available without explicit config }); ``` ### Additional context The workaround is to always set the secret explicitly (or set `BETTER_AUTH_SECRET`), but this breaks the zero-config DX that `betterAuth()` provides for local development. A simple fix would be to import `DEFAULT_SECRET` in `getCookieCache` and use it as a fallback when `process.env.NODE_ENV !== "production"`, matching the server's behavior.
GiteaMirror added the lockedbug labels 2026-04-15 19:03:25 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 7, 2026):

This is a valid bug — I can confirm the inconsistency you've identified.

Looking at the code:

As you suggested, the fix would be to import DEFAULT_SECRET in getCookieCache() and apply the same environment-aware fallback logic used in betterAuth().

In the meantime, the workaround is to explicitly pass the secret or set BETTER_AUTH_SECRET in your dev environment.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:4015482745 --> @dosubot[bot] commented on GitHub (Mar 7, 2026): <!-- Answer --> This is a valid bug — I can confirm the inconsistency you've identified. Looking at the code: - [`betterAuth()` falls back to `DEFAULT_SECRET`](https://github.com/better-auth/better-auth/blob/7fefc2bbed2b66b2349ca182144b10eff171e345/packages/better-auth/src/context/create-context.ts#L154-L171) in non-production environments when no secret is configured - [`getCookieCache()` only checks `config?.secret || env.BETTER_AUTH_SECRET`](https://github.com/better-auth/better-auth/blob/7fefc2bbed2b66b2349ca182144b10eff171e345/packages/better-auth/src/cookies/index.ts#L480-L485) and throws immediately if neither is set — no `DEFAULT_SECRET` fallback exists As you suggested, the fix would be to import `DEFAULT_SECRET` in `getCookieCache()` and apply the same environment-aware fallback logic used in `betterAuth()`. In the meantime, the workaround is to explicitly pass the secret or set `BETTER_AUTH_SECRET` in your dev environment. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/aff75934-4ee6-4917-b4d1-a187ba50d67a?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20valid%20bug%20%E2%80%94%20I%20can%20confirm%20the%20inconsistency%20you%27ve%20identified.%20%0A%0ALooking%20at%20the%20code%3A%0A-%20%5B%60betterAuth%28%29%60%20falls%20back%20to%20%60DEFAULT_SECRET%60%5D%28https%3A//github.com/better-auth/better-auth/blob/7fefc2bbed2b66b2349ca182144b10eff171e345/packages/better-auth/src/context/create-context.ts%23L154-L171%29%20in%20non-production%20environments%20when%20no%20secret%20is%20configured%0A-%20%5B%60getCookieCache%28%29%60%20only%20checks%20%60config%3F.secret%20%7C%7C%20env.BETTER_AUTH_SECRET%60%5D%28https%3A//github.com/better-auth/better-auth/blob/7fefc2bbed2b66b2349ca182144b10eff171e345/packages/better-auth/src/cookies/index.ts%23L480-L485%29%20and%20throws%20immediately%20if%20neither%20is%20set%20%E2%80%94%20no%20%60DEFAULT_SECRET%60%20fallback%20exists%0A%0AAs%20you%20suggested%2C%20the%20fix%20would%20be%20to%20import%20%60DEFAULT_SECRET%60%20in%20%60getCookieCache%28%29%60%20and%20apply%20the%20same%20environment-aware%20fallback%20logic%20used%20in%20%60betterAuth%28%29%60.%0A%0AIn%20the%20meantime%2C%20the%20workaround%20is%20to%20explicitly%20pass%20the%20secret%20or%20set%20%60BETTER_AUTH_SECRET%60%20in%20your%20dev%20environment.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/8469)
Author
Owner

@himself65 commented on GitHub (Mar 7, 2026):

This is intentional behavior rather than a bug. getCookieCache is designed to be used in separate middleware outside the auth server, so it explicitly requires the secret to be provided — either via the secret option or the BETTER_AUTH_SECRET environment variable.

Silently falling back to the default secret in this context could mask real misconfigurations, especially if production detection isn't reliable.

The fix is to set BETTER_AUTH_SECRET in your environment or pass secret explicitly:

const session = await getCookieCache(request, {
  secret: process.env.BETTER_AUTH_SECRET,
});
<!-- gh-comment-id:4015574933 --> @himself65 commented on GitHub (Mar 7, 2026): This is intentional behavior rather than a bug. `getCookieCache` is designed to be used in separate middleware outside the auth server, so it explicitly requires the secret to be provided — either via the `secret` option or the `BETTER_AUTH_SECRET` environment variable. Silently falling back to the default secret in this context could mask real misconfigurations, especially if production detection isn't reliable. The fix is to set `BETTER_AUTH_SECRET` in your environment or pass `secret` explicitly: ```typescript const session = await getCookieCache(request, { secret: process.env.BETTER_AUTH_SECRET, }); ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#19730