Session token cookie not set when using reactStartCookies plugin with session-related plugins in TanStack Start #2224

Closed
opened 2026-03-13 09:35:42 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @leonardomso on GitHub (Oct 28, 2025).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Clone the minimal reproduction repository: https://github.com/leonardomso/tanstack-better-auth-session
  2. Install dependencies: bun install
  3. Set up environment variables (see .env.example)
  4. Set up PostgreSQL database and run migrations: npx @better-auth/cli migrate
  5. Start the development server: bun run dev
  6. Navigate to the login page and click "Sign in with Google"
  7. Complete the Google OAuth flow
  8. Open browser DevTools → Application → Cookies
  9. Observe that the session token cookie is missing

Alternatively, test different configurations by modifying src/lib/auth.ts:

  • Config 1: All plugins enabled (multiSession, lastLoginMethod, oneTap, reactStartCookies) → Session cookie not set
  • Config 2: Enable session cache (lines 55-60) → Session cookie not set
  • Config 3: Only reactStartCookies() plugin → Session cookie works

Current vs. Expected behavior

Current behavior:
The session token cookie is not set in the browser when using reactStartCookies() plugin together with any of these session-related plugins: multiSession(), lastLoginMethod(), or oneTap(). The issue also occurs when enabling session cookie cache.

Expected behavior:
The session token cookie should be properly set in the browser after successful authentication, regardless of which plugins are enabled or whether session cookie cache is configured.

Workaround:
Authentication works correctly when removing all session-related plugins and keeping only reactStartCookies() for TanStack Start compatibility.

What version of Better Auth are you using?

1.3.33

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.0.0",
    "cpuCount": 12,
    "totalMemory": "64.00 GB"
  },
  "node": {
    "version": "v23.6.0",
    "env": "development"
  },
  "packageManager": {
    "name": "bun",
    "version": "1.3.1"
  },
  "frameworks": [
    {
      "name": "@tanstack/react-start",
      "version": "^1.133.34"
    },
    {
      "name": "@tanstack/react-router",
      "version": "1.133.32"
    },
    {
      "name": "react",
      "version": "^19.2.0"
    }
  ],
  "databases": [
    {
      "name": "postgres",
      "version": "^3.4.7"
    },
    {
      "name": "drizzle-orm",
      "version": "^0.44.7"
    }
  ],
  "betterAuth": {
    "version": "^1.3.33",
    "config": {
      "baseURL": "process.env.VITE_BASE_URL",
      "secret": "process.env.BETTER_AUTH_SECRET",
      "trustedOrigins": [
        "process.env.VITE_BASE_URL"
      ],
      "socialProviders": {
        "google": {
          "clientId": "process.env.GOOGLE_CLIENT_ID",
          "clientSecret": "process.env.GOOGLE_CLIENT_SECRET",
          "accessType": "offline",
          "prompt": "select_account"
        }
      },
      "plugins": [
        {
          "name": "multiSession",
          "config": {
            "id": "multi-session"
          }
        },
        {
          "name": "lastLoginMethod",
          "config": {
            "id": "last-login-method"
          }
        },
        {
          "name": "oneTap",
          "config": {
            "id": "one-tap"
          }
        },
        {
          "name": "reactStartCookies",
          "config": {
            "id": "react-start-cookies"
          }
        }
      ]
    }
  }
}

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

Client

Auth config (if applicable)

export const auth = betterAuth({
  baseURL: process.env.VITE_BASE_URL || "",
  secret: process.env.BETTER_AUTH_SECRET || "",
  trustedOrigins: [process.env.VITE_BASE_URL || ""],
  plugins: [
    multiSession(),      // Causes issue
    lastLoginMethod(),   // Causes issue
    oneTap(),           // Causes issue
    reactStartCookies(), // Required for TanStack Start
  ],
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: {
      user: schema.user,
      session: schema.session,
      account: schema.account,
      verification: schema.verification,
    },
  }),
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID || "",
      clientSecret: process.env.GOOGLE_CLIENT_SECRET || "",
      accessType: "offline",
      prompt: "select_account",
    },
  },
  // Also causes issues when enabled:
  // session: {
  //   cookieCache: {
  //     enabled: true,
  //     maxAge: 5 * 60, // 5 minutes
  //   },
  // },
});

Additional context

No response

Originally created by @leonardomso on GitHub (Oct 28, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Clone the minimal reproduction repository: https://github.com/leonardomso/tanstack-better-auth-session 2. Install dependencies: `bun install` 3. Set up environment variables (see `.env.example`) 4. Set up PostgreSQL database and run migrations: `npx @better-auth/cli migrate` 5. Start the development server: `bun run dev` 6. Navigate to the login page and click "Sign in with Google" 7. Complete the Google OAuth flow 8. Open browser DevTools → Application → Cookies 9. Observe that the session token cookie is missing Alternatively, test different configurations by modifying `src/lib/auth.ts`: - **Config 1**: All plugins enabled (`multiSession`, `lastLoginMethod`, `oneTap`, `reactStartCookies`) → ❌ Session cookie not set - **Config 2**: Enable session cache (lines 55-60) → ❌ Session cookie not set - **Config 3**: Only `reactStartCookies()` plugin → ✅ Session cookie works ### Current vs. Expected behavior **Current behavior:** The session token cookie is not set in the browser when using `reactStartCookies()` plugin together with any of these session-related plugins: `multiSession()`, `lastLoginMethod()`, or `oneTap()`. The issue also occurs when enabling session cookie cache. **Expected behavior:** The session token cookie should be properly set in the browser after successful authentication, regardless of which plugins are enabled or whether session cookie cache is configured. **Workaround:** Authentication works correctly when removing all session-related plugins and keeping only `reactStartCookies()` for TanStack Start compatibility. ### What version of Better Auth are you using? 1.3.33 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.0.0", "cpuCount": 12, "totalMemory": "64.00 GB" }, "node": { "version": "v23.6.0", "env": "development" }, "packageManager": { "name": "bun", "version": "1.3.1" }, "frameworks": [ { "name": "@tanstack/react-start", "version": "^1.133.34" }, { "name": "@tanstack/react-router", "version": "1.133.32" }, { "name": "react", "version": "^19.2.0" } ], "databases": [ { "name": "postgres", "version": "^3.4.7" }, { "name": "drizzle-orm", "version": "^0.44.7" } ], "betterAuth": { "version": "^1.3.33", "config": { "baseURL": "process.env.VITE_BASE_URL", "secret": "process.env.BETTER_AUTH_SECRET", "trustedOrigins": [ "process.env.VITE_BASE_URL" ], "socialProviders": { "google": { "clientId": "process.env.GOOGLE_CLIENT_ID", "clientSecret": "process.env.GOOGLE_CLIENT_SECRET", "accessType": "offline", "prompt": "select_account" } }, "plugins": [ { "name": "multiSession", "config": { "id": "multi-session" } }, { "name": "lastLoginMethod", "config": { "id": "last-login-method" } }, { "name": "oneTap", "config": { "id": "one-tap" } }, { "name": "reactStartCookies", "config": { "id": "react-start-cookies" } } ] } } } ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript export const auth = betterAuth({ baseURL: process.env.VITE_BASE_URL || "", secret: process.env.BETTER_AUTH_SECRET || "", trustedOrigins: [process.env.VITE_BASE_URL || ""], plugins: [ multiSession(), // Causes issue lastLoginMethod(), // Causes issue oneTap(), // Causes issue reactStartCookies(), // Required for TanStack Start ], database: drizzleAdapter(db, { provider: "pg", schema: { user: schema.user, session: schema.session, account: schema.account, verification: schema.verification, }, }), socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID || "", clientSecret: process.env.GOOGLE_CLIENT_SECRET || "", accessType: "offline", prompt: "select_account", }, }, // Also causes issues when enabled: // session: { // cookieCache: { // enabled: true, // maxAge: 5 * 60, // 5 minutes // }, // }, }); ``` ### Additional context _No response_
GiteaMirror added the bugtanstack-start labels 2026-03-13 09:35:42 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Oct 28, 2025):

Hi @leonardomso! I'm Dosu and I’m helping the better-auth team.

This issue is caused by how multiple session-related plugins (like multiSession, lastLoginMethod, oneTap) interact with reactStartCookies and TanStack Start's middleware. When these plugins are combined, their hooks all try to set or modify cookies, but TanStack Start does not automatically forward set-cookie headers from server responses to the browser. As a result, the session token cookie is not set unless you handle the cookie propagation explicitly.

To work around this, you can either:

  • Use only reactStartCookies() (as you've found), or
  • Replace reactStartCookies with a custom plugin that parses the set-cookie header from the response and sets cookies using TanStack Start's setCookie utility. This approach is documented by users who ran into the same problem and resolved it by copying the logic from reactStartCookies but using TanStack's cookie utilities directly (example workaround and explanation).

Also, make sure the plugin that manages cookies is last in your plugins array, as plugin order can affect which cookies are ultimately set.

If you want to keep all plugins, you must ensure your middleware or server actions extract the set-cookie header from the Better Auth response (e.g., by calling getSession({ asResponse: true })) and set it on the outgoing response to the client. More details and code samples are available in this discussion.

This is not a bug in Better Auth itself, but a result of how TanStack Start handles server responses and cookie propagation.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Oct 28, 2025): <!-- Greeting --> Hi @leonardomso! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This issue is caused by how multiple session-related plugins (like `multiSession`, `lastLoginMethod`, `oneTap`) interact with `reactStartCookies` and TanStack Start's middleware. When these plugins are combined, their hooks all try to set or modify cookies, but TanStack Start does not automatically forward `set-cookie` headers from server responses to the browser. As a result, the session token cookie is not set unless you handle the cookie propagation explicitly. To work around this, you can either: - Use only `reactStartCookies()` (as you've found), or - Replace `reactStartCookies` with a custom plugin that parses the `set-cookie` header from the response and sets cookies using TanStack Start's `setCookie` utility. This approach is documented by users who ran into the same problem and resolved it by copying the logic from `reactStartCookies` but using TanStack's cookie utilities directly ([example workaround and explanation](https://github.com/better-auth/better-auth/issues/4389#issuecomment-3383331495)). Also, make sure the plugin that manages cookies is last in your plugins array, as plugin order can affect which cookies are ultimately set. If you want to keep all plugins, you must ensure your middleware or server actions extract the `set-cookie` header from the Better Auth response (e.g., by calling `getSession({ asResponse: true })`) and set it on the outgoing response to the client. More details and code samples are available in [this discussion](https://github.com/better-auth/better-auth/discussions/4231). This is not a bug in Better Auth itself, but a result of how TanStack Start handles server responses and cookie propagation. <!-- 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/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/c178bd5e-0fd0-454d-8d5e-8c85f5870cac?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&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/5639)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#2224