[GH-ISSUE #4969] Update to 1.3.23 and logging to google leads to state_mismatch #10126

Closed
opened 2026-04-13 06:03:05 -05:00 by GiteaMirror · 21 comments
Owner

Originally created by @AceCodePt on GitHub (Sep 29, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4969

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

I installed the latest version:
"better-auth": "^1.3.23",

from 1.3.12

I'm trying to have a link to social in astro and have the login from astro.
After logging I'm getting the following screen:

Image

Current vs. Expected behavior

It should just work...
But it doesn't

What version of Better Auth are you using?

1.3.23

System info

{
  "system": {
    "platform": "linux",
    "arch": "x64",
    "version": "#78-Ubuntu SMP PREEMPT_DYNAMIC Tue Aug 12 11:34:18 UTC 2025",
    "release": "6.8.0-78-generic",
    "cpuCount": 20,
    "cpuModel": "12th Gen Intel(R) Core(TM) i7-12700H",
    "totalMemory": "62.50 GB",
    "freeMemory": "55.29 GB"
  },
  "node": {
    "version": "v24.6.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.17.1"
  },
  "frameworks": [
    {
      "name": "astro",
      "version": "^5.14.1"
    }
  ],
  "databases": [
    {
      "name": "postgres",
      "version": "^3.4.7"
    }
  ],
  "betterAuth": {
    "version": "^1.3.23",
    "config": {
      "socialProviders": {
        "google": {
          "clientId": "[REDACTED]",
          "clientSecret": "[REDACTED]",
          "enabled": true
        }
      },
      "database": {
        "dialect": {},
        "type": "postgres"
      },
      "user": {
        "fields": {
          "emailVerified": "email_verified",
          "createdAt": "created_at",
          "updatedAt": "updated_at"
        }
      },
      "session": {
        "fields": {
          "userId": "user_id",
          "expiresAt": "expires_at",
          "createdAt": "created_at",
          "updatedAt": "updated_at",
          "ipAddress": "ip_address",
          "userAgent": "user_agent"
        }
      },
      "account": {
        "fields": {
          "userId": "user_id",
          "accountId": "account_id",
          "providerId": "provider_id",
          "accessToken": "[REDACTED]",
          "refreshToken": "[REDACTED]",
          "idToken": "[REDACTED]",
          "accessTokenExpiresAt": "access_token_expires_at",
          "refreshTokenExpiresAt": "refresh_token_expires_at",
          "createdAt": "created_at",
          "updatedAt": "updated_at"
        }
      },
      "verification": {
        "fields": {
          "expiresAt": "expires_at",
          "createdAt": "created_at",
          "updatedAt": "updated_at"
        }
      }
    }
  }
}

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth";
import sql from "./sql";
import { PostgresJSDialect } from "kysely-postgres-js";

export const auth = betterAuth({
  socialProviders: {
    google: {
      clientId: process.env?.GOOGLE_CLIENT_ID!,
      clientSecret: process.env?.GOOGLE_CLIENT_SECRET!,
      enabled: true,
    },
  },
  database: {
    dialect: new PostgresJSDialect({
      postgres: sql,
    }),
    type: "postgres",
  },
  user: {
    fields: {
      emailVerified: "email_verified",
      createdAt: "created_at",
      updatedAt: "updated_at",
    },
  },
  session: {
    fields: {
      userId: "user_id",
      expiresAt: "expires_at",
      createdAt: "created_at",
      updatedAt: "updated_at",
      ipAddress: "ip_address",
      userAgent: "user_agent",
    },
  },
  account: {
    fields: {
      userId: "user_id",
      accountId: "account_id",
      providerId: "provider_id",
      accessToken: "access_token",
      refreshToken: "refresh_token",
      idToken: "id_token",
      accessTokenExpiresAt: "access_token_expires_at",
      refreshTokenExpiresAt: "refresh_token_expires_at",
      createdAt: "created_at",
      updatedAt: "updated_at",
    },
  },
  verification: {
    fields: {
      expiresAt: "expires_at",
      createdAt: "created_at",
      updatedAt: "updated_at",
    },
  },
});

Additional context

Multiple changes where made:
first the sql:

const sql = postgres({
  connection: {
    search_path: "public, auth",
  },
...
})

All my tables are in auth schema

I also made modifications to the middleware to support the use of htmx:

import logger from "@/lib/logger";
import safeAsync from "@/lib/util/safeAsync";
import { auth } from "@auth";
import type { APIRoute } from "astro";
import { z } from "astro/zod";

export const ALL: APIRoute = async (ctx) => {
  // ctx.request.headers.set("x-forwarded-for", ctx.clientAddress);
  const response = await safeAsync(auth.handler(ctx.request));

  if (response.error) {
    logger.error(`Something didn't work with better auth`, response.error);
    return new Response("Unexpected error occured", { status: 500 });
  }

  if (ctx.url.pathname === "/api/auth/sign-in/social") {
    const rawBodyResponse = await safeAsync(response.data.json());
    if (rawBodyResponse.error) {
      logger.error(`Couldn't parse raw response as json`, response.error);
      return new Response("Unexpected error occured", { status: 500 });
    }

    const expectedBody = z
      .object({ url: z.string().url() })
      .safeParse(rawBodyResponse.data);

    if (expectedBody.error) {
      logger.error(
        `The body received from better auth was malformed`,
        response.error,
      );
      return new Response("Unexpected error occured", { status: 500 });
    }

    return new Response("", {
      headers: { "HX-Redirect": expectedBody.data.url },
    });
  }

  console.log(ctx.url, response.data);

  return response.data;
};

Originally created by @AceCodePt on GitHub (Sep 29, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4969 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce I installed the latest version: "better-auth": "^1.3.23", from 1.3.12 I'm trying to have a link to social in astro and have the login from astro. After logging I'm getting the following screen: <img width="1642" height="888" alt="Image" src="https://github.com/user-attachments/assets/a34ff9f2-3ed6-4fe7-a31c-ef938ae7bac6" /> ### Current vs. Expected behavior It should just work... But it doesn't ### What version of Better Auth are you using? 1.3.23 ### System info ```bash { "system": { "platform": "linux", "arch": "x64", "version": "#78-Ubuntu SMP PREEMPT_DYNAMIC Tue Aug 12 11:34:18 UTC 2025", "release": "6.8.0-78-generic", "cpuCount": 20, "cpuModel": "12th Gen Intel(R) Core(TM) i7-12700H", "totalMemory": "62.50 GB", "freeMemory": "55.29 GB" }, "node": { "version": "v24.6.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.17.1" }, "frameworks": [ { "name": "astro", "version": "^5.14.1" } ], "databases": [ { "name": "postgres", "version": "^3.4.7" } ], "betterAuth": { "version": "^1.3.23", "config": { "socialProviders": { "google": { "clientId": "[REDACTED]", "clientSecret": "[REDACTED]", "enabled": true } }, "database": { "dialect": {}, "type": "postgres" }, "user": { "fields": { "emailVerified": "email_verified", "createdAt": "created_at", "updatedAt": "updated_at" } }, "session": { "fields": { "userId": "user_id", "expiresAt": "expires_at", "createdAt": "created_at", "updatedAt": "updated_at", "ipAddress": "ip_address", "userAgent": "user_agent" } }, "account": { "fields": { "userId": "user_id", "accountId": "account_id", "providerId": "provider_id", "accessToken": "[REDACTED]", "refreshToken": "[REDACTED]", "idToken": "[REDACTED]", "accessTokenExpiresAt": "access_token_expires_at", "refreshTokenExpiresAt": "refresh_token_expires_at", "createdAt": "created_at", "updatedAt": "updated_at" } }, "verification": { "fields": { "expiresAt": "expires_at", "createdAt": "created_at", "updatedAt": "updated_at" } } } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import sql from "./sql"; import { PostgresJSDialect } from "kysely-postgres-js"; export const auth = betterAuth({ socialProviders: { google: { clientId: process.env?.GOOGLE_CLIENT_ID!, clientSecret: process.env?.GOOGLE_CLIENT_SECRET!, enabled: true, }, }, database: { dialect: new PostgresJSDialect({ postgres: sql, }), type: "postgres", }, user: { fields: { emailVerified: "email_verified", createdAt: "created_at", updatedAt: "updated_at", }, }, session: { fields: { userId: "user_id", expiresAt: "expires_at", createdAt: "created_at", updatedAt: "updated_at", ipAddress: "ip_address", userAgent: "user_agent", }, }, account: { fields: { userId: "user_id", accountId: "account_id", providerId: "provider_id", accessToken: "access_token", refreshToken: "refresh_token", idToken: "id_token", accessTokenExpiresAt: "access_token_expires_at", refreshTokenExpiresAt: "refresh_token_expires_at", createdAt: "created_at", updatedAt: "updated_at", }, }, verification: { fields: { expiresAt: "expires_at", createdAt: "created_at", updatedAt: "updated_at", }, }, }); ``` ### Additional context Multiple changes where made: first the sql: ```ts const sql = postgres({ connection: { search_path: "public, auth", }, ... }) ``` All my tables are in `auth schema` I also made modifications to the middleware to support the use of htmx: ```ts import logger from "@/lib/logger"; import safeAsync from "@/lib/util/safeAsync"; import { auth } from "@auth"; import type { APIRoute } from "astro"; import { z } from "astro/zod"; export const ALL: APIRoute = async (ctx) => { // ctx.request.headers.set("x-forwarded-for", ctx.clientAddress); const response = await safeAsync(auth.handler(ctx.request)); if (response.error) { logger.error(`Something didn't work with better auth`, response.error); return new Response("Unexpected error occured", { status: 500 }); } if (ctx.url.pathname === "/api/auth/sign-in/social") { const rawBodyResponse = await safeAsync(response.data.json()); if (rawBodyResponse.error) { logger.error(`Couldn't parse raw response as json`, response.error); return new Response("Unexpected error occured", { status: 500 }); } const expectedBody = z .object({ url: z.string().url() }) .safeParse(rawBodyResponse.data); if (expectedBody.error) { logger.error( `The body received from better auth was malformed`, response.error, ); return new Response("Unexpected error occured", { status: 500 }); } return new Response("", { headers: { "HX-Redirect": expectedBody.data.url }, }); } console.log(ctx.url, response.data); return response.data; }; ```
GiteaMirror added the lockedbug labels 2026-04-13 06:03:05 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 29, 2025):

The "state_mismatch" error after upgrading to Better Auth 1.3.23 is likely due to changes in how OAuth state and session are managed, especially with custom middleware or Astro integrations. Here are the most relevant things to check:

  1. Redirect URIs: Double-check that your Google Cloud Console's "Authorized redirect URIs" exactly match your callback URLs (e.g., http://localhost:3000/api/auth/callback/google for local, and your production URL) source.

  2. Database config: Since your tables are in the auth schema and use snake_case, add schema: "auth" and casing: "snake" to your Better Auth database config. This ensures field mapping is correct and avoids subtle session/state issues source.

  3. Session/cookie propagation: The state parameter is stored in a session cookie. If your custom middleware or Astro route handling doesn't forward/set cookies correctly between the initial login and the callback, you'll get a state mismatch. Make sure cookies from the initial response are sent with the callback request. Review how your middleware handles cookies—Astro's API routes and custom header logic can sometimes drop or misroute cookies source.

  4. Breaking change in clientId handling: In 1.3.23, if you provide an array of clientIds, only the first is used in all OAuth requests. If you previously relied on multiple clientIds, this could break state/session validation source.

  5. Timestamps: If you see any errors about timestamps, ensure all timestamp fields in your DB schema use JavaScript Date objects, not SQL defaults source.

If you address these areas and still see the error, focus on debugging cookie/session propagation in your middleware and Astro integration, as that's the most common cause of state mismatches after an upgrade.

To reply, just mention @dosu.


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

<!-- gh-comment-id:3347351786 --> @dosubot[bot] commented on GitHub (Sep 29, 2025): <!-- Answer --> The "state_mismatch" error after upgrading to Better Auth 1.3.23 is likely due to changes in how OAuth state and session are managed, especially with custom middleware or Astro integrations. Here are the most relevant things to check: 1. **Redirect URIs**: Double-check that your Google Cloud Console's "Authorized redirect URIs" exactly match your callback URLs (e.g., `http://localhost:3000/api/auth/callback/google` for local, and your production URL) [source](https://github.com/better-auth/better-auth/issues/3062). 2. **Database config**: Since your tables are in the `auth` schema and use snake_case, add `schema: "auth"` and `casing: "snake"` to your Better Auth database config. This ensures field mapping is correct and avoids subtle session/state issues [source](https://github.com/better-auth/better-auth/issues/4789). 3. **Session/cookie propagation**: The state parameter is stored in a session cookie. If your custom middleware or Astro route handling doesn't forward/set cookies correctly between the initial login and the callback, you'll get a state mismatch. Make sure cookies from the initial response are sent with the callback request. Review how your middleware handles cookies—Astro's API routes and custom header logic can sometimes drop or misroute cookies [source](https://github.com/better-auth/better-auth/blob/f6cbdcc84ee5d2971fdcc8b23ff7c174f88cf45b/packages/better-auth/src/cookies/cookie-utils.ts). 4. **Breaking change in clientId handling**: In 1.3.23, if you provide an array of clientIds, only the first is used in all OAuth requests. If you previously relied on multiple clientIds, this could break state/session validation [source](https://github.com/better-auth/better-auth/pull/4598). 5. **Timestamps**: If you see any errors about timestamps, ensure all timestamp fields in your DB schema use JavaScript `Date` objects, not SQL defaults [source](https://github.com/better-auth/better-auth/issues/4434). If you address these areas and still see the error, focus on debugging cookie/session propagation in your middleware and Astro integration, as that's the most common cause of state mismatches after an upgrade. <!-- 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/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/50e93a9b-2f24-4874-a5aa-4a46866fa6ca?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/4969)
Author
Owner

@AceCodePt commented on GitHub (Sep 29, 2025):

  1. Checked.
  2. Made the modifications (didn't help)
  3. I see in the logs the cookies.
  4. I only provided a provider of google with a single client_id
  5. I'm using a kysely adapter so I highly doubt that that is an issue.
<!-- gh-comment-id:3347380582 --> @AceCodePt commented on GitHub (Sep 29, 2025): 1. Checked. 2. Made the modifications (didn't help) 3. I see in the logs the cookies. 4. I only provided a provider of google with a single client_id 5. I'm using a kysely adapter so I highly doubt that that is an issue.
Author
Owner

@Bekacru commented on GitHub (Sep 30, 2025):

You should set cookies on the client for state. We had a weird workaround in the previous versions that's no longer supported. The way you're using the api here is a bit weird. I suggest using authClient directly

<!-- gh-comment-id:3350195133 --> @Bekacru commented on GitHub (Sep 30, 2025): You should set cookies on the client for `state`. We had a weird workaround in the previous versions that's no longer supported. The way you're using the api here is a bit weird. I suggest using `authClient` directly
Author
Owner

@AceCodePt commented on GitHub (Sep 30, 2025):

Isn't there a way for a more server side solution?

On Tue, Sep 30, 2025, 09:40 Bereket Engida @.***> wrote:

Bekacru left a comment (better-auth/better-auth#4969)
https://github.com/better-auth/better-auth/issues/4969#issuecomment-3350195133

You should set cookies on the client for state. We had a weird workaround
in the previous versions that's no longer supported. The way you're using
the api here is a bit weird. I suggest using authClient directly


Reply to this email directly, view it on GitHub
https://github.com/better-auth/better-auth/issues/4969#issuecomment-3350195133,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AET7AOE64KBRKP7C3XMGQND3VIQU3AVCNFSM6AAAAACHZPQIQKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGNJQGE4TKMJTGM
.
You are receiving this because you authored the thread.Message ID:
@.***>

<!-- gh-comment-id:3350397385 --> @AceCodePt commented on GitHub (Sep 30, 2025): Isn't there a way for a more server side solution? On Tue, Sep 30, 2025, 09:40 Bereket Engida ***@***.***> wrote: > *Bekacru* left a comment (better-auth/better-auth#4969) > <https://github.com/better-auth/better-auth/issues/4969#issuecomment-3350195133> > > You should set cookies on the client for state. We had a weird workaround > in the previous versions that's no longer supported. The way you're using > the api here is a bit weird. I suggest using authClient directly > > — > Reply to this email directly, view it on GitHub > <https://github.com/better-auth/better-auth/issues/4969#issuecomment-3350195133>, > or unsubscribe > <https://github.com/notifications/unsubscribe-auth/AET7AOE64KBRKP7C3XMGQND3VIQU3AVCNFSM6AAAAACHZPQIQKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGNJQGE4TKMJTGM> > . > You are receiving this because you authored the thread.Message ID: > ***@***.***> >
Author
Owner

@Dougsworth commented on GitHub (Sep 30, 2025):

hi were you able to resolve this?

<!-- gh-comment-id:3352293588 --> @Dougsworth commented on GitHub (Sep 30, 2025): hi were you able to resolve this?
Author
Owner

@rohovskoi commented on GitHub (Oct 2, 2025):

@Bekacru Hey 👋

Are there any other endpoints affected except for social and SSO auth?

I implemented everything on my server and on my client I call my custom server endpoints (I don't use createAuthClient()) at all.

Do you plan for other endpoints the same? This would be painful to migrate..

<!-- gh-comment-id:3363591956 --> @rohovskoi commented on GitHub (Oct 2, 2025): @Bekacru Hey 👋 Are there any other endpoints affected except for social and SSO auth? I implemented everything on my server and on my client I call my custom server endpoints (I don't use `createAuthClient()`) at all. Do you plan for other endpoints the same? This would be painful to migrate..
Author
Owner

@Bekacru commented on GitHub (Oct 2, 2025):

Hey, only oauth (social,sso,generic oauth) endpoints are affected

<!-- gh-comment-id:3363597127 --> @Bekacru commented on GitHub (Oct 2, 2025): Hey, only oauth (social,sso,generic oauth) endpoints are affected
Author
Owner

@Balance8 commented on GitHub (Oct 3, 2025):

is this fixed? I am still running into it with github

<!-- gh-comment-id:3364304881 --> @Balance8 commented on GitHub (Oct 3, 2025): is this fixed? I am still running into it with github
Author
Owner

@danbarbarito commented on GitHub (Oct 12, 2025):

I'm still seeing this too. Downgrading to version 1.2.12 works for now..

<!-- gh-comment-id:3395405873 --> @danbarbarito commented on GitHub (Oct 12, 2025): I'm still seeing this too. Downgrading to version 1.2.12 works for now..
Author
Owner

@jjjrmy commented on GitHub (Oct 13, 2025):

the last version working for me is 1.3.18, if I upgrade past that then I get state_mismatch

<!-- gh-comment-id:3395762658 --> @jjjrmy commented on GitHub (Oct 13, 2025): the last version working for me is `1.3.18`, if I upgrade past that then I get `state_mismatch`
Author
Owner

@AceCodePt commented on GitHub (Oct 13, 2025):

@Bekacru The issue still persist. Further more if is possible I would like a server side solution.
While I can create my own endpoint to call the auth endpoint I'm curious for why not call the better-auth endpoint itself.

<!-- gh-comment-id:3396696452 --> @AceCodePt commented on GitHub (Oct 13, 2025): @Bekacru The issue still persist. Further more if is possible I would like a server side solution. While I can create my own endpoint to call the auth endpoint I'm curious for why not call the better-auth endpoint itself.
Author
Owner

@Fruup commented on GitHub (Oct 13, 2025):

@Bekacru What exactly do you mean by "You should set cookies on the client for state"? I can't find any documentation on this, unfortunately. I'm using the authClient from the SDK.


Edit:

I found out that the authClient sets this cookie automatically. My issue is that I'm trying to authenticate from domain a.com while better-auth is running at domain another domain b.com. The cookies will only be available at domain b.com.

Is there a way to achieve cross-domain authentication using SSO, or is this out of scope for this library?

I found out this is possible by setting the following:

betterAuth({
  ...,
  advanced: {
    defaultCookieAttributes: {
      sameSite: 'None', // this enables cross-site cookies
      secure: true, // required for SameSite=None
    },
  }
})

This is exactly what I wanted :) The trustedOrigins option is also respected, so I don't see a huge security implication here.

<!-- gh-comment-id:3397804378 --> @Fruup commented on GitHub (Oct 13, 2025): @Bekacru What exactly do you mean by "You should set cookies on the client for `state`"? I can't find any documentation on this, unfortunately. I'm using the `authClient` from the SDK. --- ## Edit: ~~I found out that the `authClient` sets this cookie automatically. My issue is that I'm trying to authenticate from domain `a.com` while better-auth is running at domain another domain `b.com`. The cookies will only be available at domain `b.com`.~~ ~~Is there a way to achieve cross-domain authentication using SSO, or is this out of scope for this library?~~ I found out this is possible by setting the following: ```ts betterAuth({ ..., advanced: { defaultCookieAttributes: { sameSite: 'None', // this enables cross-site cookies secure: true, // required for SameSite=None }, } }) ``` This is exactly what I wanted :) The `trustedOrigins` option is also respected, so I don't see a huge security implication here.
Author
Owner

@abhijitxy commented on GitHub (Nov 5, 2025):

downgraded and it's working now

<!-- gh-comment-id:3492900536 --> @abhijitxy commented on GitHub (Nov 5, 2025): downgraded and it's working now
Author
Owner

@jdtzmn commented on GitHub (Nov 5, 2025):

@abhijitxy to what version?

<!-- gh-comment-id:3492936011 --> @jdtzmn commented on GitHub (Nov 5, 2025): @abhijitxy to what version?
Author
Owner

@abhijitxy commented on GitHub (Nov 5, 2025):

@abhijitxy to what version?

1.2.12

<!-- gh-comment-id:3492942289 --> @abhijitxy commented on GitHub (Nov 5, 2025): > [@abhijitxy](https://github.com/abhijitxy) to what version? 1.2.12
Author
Owner

@martinriviere commented on GitHub (Nov 6, 2025):

Hi! Aren't there still no solutions to perform an OAuth sign in on the server?
The OAuth generic plugin documentation still shows that possibility, but it seems it can't be done?
The signInWithOAuth2 api method returns an url that we can we can use to redirect request, but still get a state_mismatch error after sign in 😕
Downgrading and using authClient is unfortunately not an option in one of my cases, where we have no control over client and is 100% SSR...

<!-- gh-comment-id:3496188961 --> @martinriviere commented on GitHub (Nov 6, 2025): Hi! Aren't there still no solutions to perform an OAuth sign in on the server? The OAuth generic plugin [documentation](https://www.better-auth.com/docs/plugins/generic-oauth#api-method-sign-in-oauth2) still shows that possibility, but it seems it can't be done? The `signInWithOAuth2` api method returns an url that we can we can use to redirect request, but still get a `state_mismatch` error after sign in 😕 Downgrading and using authClient is unfortunately not an option in one of my cases, where we have no control over client and is 100% SSR...
Author
Owner

@JoshuaSmeda commented on GitHub (Nov 9, 2025):

I'm getting the same error on version 1.3.32

<!-- gh-comment-id:3508006762 --> @JoshuaSmeda commented on GitHub (Nov 9, 2025): I'm getting the same error on version `1.3.32`
Author
Owner

@geekyharsh05 commented on GitHub (Nov 18, 2025):

@Bekacru I am getting the same error on Version 1.3.34, only OAuth is not working, Signin with creds is working (email, pass).

<!-- gh-comment-id:3547188846 --> @geekyharsh05 commented on GitHub (Nov 18, 2025): @Bekacru I am getting the same error on Version `1.3.34,` only **OAuth** is not working, Signin with creds is working (email, pass).
Author
Owner

@letstri commented on GitHub (Nov 18, 2025):

For now you can use temp solution to disable state mismatch with this plugin:

export function skipStateMismatch(): BetterAuthPlugin {
  return {
    id: 'skip-state-mismatch',
    init(ctx) {
      return {
        context: {
          ...ctx,
          oauthConfig: {
            skipStateCookieCheck: true,
            ...ctx?.oauthConfig,
          },
        },
      }
    },
  }
}
<!-- gh-comment-id:3547344061 --> @letstri commented on GitHub (Nov 18, 2025): For now you can use temp solution to disable state mismatch with this plugin: ``` export function skipStateMismatch(): BetterAuthPlugin { return { id: 'skip-state-mismatch', init(ctx) { return { context: { ...ctx, oauthConfig: { skipStateCookieCheck: true, ...ctx?.oauthConfig, }, }, } }, } } ```
Author
Owner

@thatanjan commented on GitHub (Jan 25, 2026):

I'm getting the same error.
Downgraded to v1.2.12 and it is working.
My code:

export async function signInWithGoogle() {
  const result = await auth.api.signInSocial({
    body: {
      provider: "google",
      callbackURL: "/", // Redirect here after successful Google login
    },
  });
<!-- gh-comment-id:3796809431 --> @thatanjan commented on GitHub (Jan 25, 2026): I'm getting the same error. Downgraded to v1.2.12 and it is working. My code: ```javascript export async function signInWithGoogle() { const result = await auth.api.signInSocial({ body: { provider: "google", callbackURL: "/", // Redirect here after successful Google login }, }); ```
Author
Owner

@github-actions[bot] commented on GitHub (Apr 1, 2026):

This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.

<!-- gh-comment-id:4166562743 --> @github-actions[bot] commented on GitHub (Apr 1, 2026): This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10126