[GH-ISSUE #7777] SSO SAML ACS is broken for SP initiated auth following #6675 #28224

Closed
opened 2026-04-17 19:40:51 -05:00 by GiteaMirror · 7 comments
Owner

Originally created by @rbayliss on GitHub (Feb 3, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/7777

Originally assigned to: @Paola3stefania on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create a new SSO provider using SAML.
  2. Log in using SP-initiated auth.
  3. Find that you are redirected from /sso/saml2/sp/acs/<provider id> to /sso/saml2/sp/acs/<long ID string>.

Current vs. Expected behavior

In https://github.com/better-auth/better-auth/pull/6675, relay state was switched from a simple string to an object stored in the verification table. This verification ID becomes the RelayState parameter passed to the SAML provider, and comes back looking like the callback URL. The ACS handler doesn't understand this, and treats the verification ID (RelayState) as the redirect URL.

What version of Better Auth are you using?

1.4.18

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:56 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6041",
    "release": "25.2.0",
    "cpuCount": 14,
    "cpuModel": "Apple M4 Pro",
    "totalMemory": "48.00 GB",
    "freeMemory": "1.44 GB"
  },
  "node": {
    "version": "v24.13.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "11.8.0"
  },
  "frameworks": [
    {
      "name": "hono",
      "version": "^4.11.7"
    }
  ],
  "databases": [
    {
      "name": "pg",
      "version": "^8.16.3"
    },
    {
      "name": "drizzle",
      "version": "^0.45.0"
    }
  ],
  "betterAuth": {
    "version": "^1.4.18",
    "config": null
  }
}

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  plugins: [sso({})],
});

Additional context

No response

Originally created by @rbayliss on GitHub (Feb 3, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/7777 Originally assigned to: @Paola3stefania on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create a new SSO provider using SAML. 2. Log in using SP-initiated auth. 3. Find that you are redirected from `/sso/saml2/sp/acs/<provider id>` to `/sso/saml2/sp/acs/<long ID string>`. ### Current vs. Expected behavior In https://github.com/better-auth/better-auth/pull/6675, relay state was switched from a simple string to an object stored in the verification table. This verification ID becomes the RelayState parameter passed to the SAML provider, and comes back looking like the callback URL. The ACS handler doesn't understand this, and treats the verification ID (`RelayState`) as the redirect URL. ### What version of Better Auth are you using? 1.4.18 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:56 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6041", "release": "25.2.0", "cpuCount": 14, "cpuModel": "Apple M4 Pro", "totalMemory": "48.00 GB", "freeMemory": "1.44 GB" }, "node": { "version": "v24.13.0", "env": "development" }, "packageManager": { "name": "npm", "version": "11.8.0" }, "frameworks": [ { "name": "hono", "version": "^4.11.7" } ], "databases": [ { "name": "pg", "version": "^8.16.3" }, { "name": "drizzle", "version": "^0.45.0" } ], "betterAuth": { "version": "^1.4.18", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ plugins: [sso({})], }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-17 19:40:51 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Feb 3, 2026):

It appears that the issue you are experiencing with the SSO SAML ACS might be related to the changes introduced in pull request #6675, which switched the relay state from a string to an object. This modification affected how the ACS handler processes the verification ID as it is now misinterpreting the verification ID as the redirect URL.

To troubleshoot this behavior, you might consider the following steps:

  1. Review the implementation of your ACS handler to ensure it correctly processes the expected format of the RelayState.
  2. Check if you are passing the correct callback URL and ensure it matches the new expectations established by the above pull request.
  3. You may want to verify that the configurations specified for the SSO provider align with the updates from the change log.

If you continue to see issues after these adjustments, it might be helpful to tag @bekacru or @ping__ so they can provide further assistance.

What specific error message are you encountering, or what behavior are you observing that indicates the ACS is not functioning as expected?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3842814582 --> @better-auth-agent[bot] commented on GitHub (Feb 3, 2026): It appears that the issue you are experiencing with the SSO SAML ACS might be related to the changes introduced in pull request #6675, which switched the relay state from a string to an object. This modification affected how the ACS handler processes the verification ID as it is now misinterpreting the verification ID as the redirect URL. To troubleshoot this behavior, you might consider the following steps: 1. Review the implementation of your ACS handler to ensure it correctly processes the expected format of the RelayState. 2. Check if you are passing the correct callback URL and ensure it matches the new expectations established by the above pull request. 3. You may want to verify that the configurations specified for the SSO provider align with the updates from the change log. If you continue to see issues after these adjustments, it might be helpful to tag @bekacru or @ping__ so they can provide further assistance. What specific error message are you encountering, or what behavior are you observing that indicates the ACS is not functioning as expected? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@dosubot[bot] commented on GitHub (Feb 3, 2026):

This is a confirmed regression after #6675. The ACS handler now receives RelayState as a verification ID (not a URL), but still treats it as the final redirect target, so you get redirected to /sso/saml2/sp/acs/<verificationId> instead of your intended callback. The correct behavior is to resolve RelayState as a verification ID and look up the stored callbackURL in the verification table, just like the SAML callback handler does. This bug is present in v1.4.18 and no patch has been merged yet to fix it (source).

As a workaround for 404s in IdP-initiated flows, you can add explicit GET and POST handlers for your SAML callback route, but this does not fix the ACS handler's RelayState parsing bug (source). Changing the callbackUrl is not a valid solution, as the SAML spec requires it to be the ACS URL (source).

If you need a temporary fix, you could monkey-patch the ACS handler to parse RelayState as a verification ID and fetch the stored callbackURL, similar to how parseRelayState is used in the callback handler. If you want a code example for this workaround, let me know.

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:3842853258 --> @dosubot[bot] commented on GitHub (Feb 3, 2026): <!-- Answer --> This is a confirmed regression after #6675. The ACS handler now receives RelayState as a verification ID (not a URL), but still treats it as the final redirect target, so you get redirected to `/sso/saml2/sp/acs/<verificationId>` instead of your intended callback. The correct behavior is to resolve RelayState as a verification ID and look up the stored callbackURL in the verification table, just like the SAML callback handler does. This bug is present in v1.4.18 and no patch has been merged yet to fix it ([source](https://github.com/better-auth/better-auth/blob/583f12fb7db38681ee882d219ce3895faa4a6976/packages/sso/src/routes/sso.ts#L2281-L2726)). As a workaround for 404s in IdP-initiated flows, you can add explicit GET and POST handlers for your SAML callback route, but this does not fix the ACS handler's RelayState parsing bug ([source](https://github.com/better-auth/better-auth/issues/6615#issuecomment-3638666970)). Changing the callbackUrl is not a valid solution, as the SAML spec requires it to be the ACS URL ([source](https://github.com/better-auth/better-auth/pull/6669)). If you need a temporary fix, you could monkey-patch the ACS handler to parse RelayState as a verification ID and fetch the stored callbackURL, similar to how `parseRelayState` is used in the callback handler. If you want a code example for this workaround, let me know. <!-- 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/82ce79f3-e8e0-40c7-8131-3c091adb1acc?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/82ce79f3-e8e0-40c7-8131-3c091adb1acc?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/82ce79f3-e8e0-40c7-8131-3c091adb1acc?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/82ce79f3-e8e0-40c7-8131-3c091adb1acc?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/82ce79f3-e8e0-40c7-8131-3c091adb1acc?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/82ce79f3-e8e0-40c7-8131-3c091adb1acc?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/82ce79f3-e8e0-40c7-8131-3c091adb1acc?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%20confirmed%20regression%20after%20%236675.%20The%20ACS%20handler%20now%20receives%20RelayState%20as%20a%20verification%20ID%20%28not%20a%20URL%29%2C%20but%20still%20treats%20it%20as%20the%20final%20redirect%20target%2C%20so%20you%20get%20redirected%20to%20%60/sso/saml2/sp/acs/%3CverificationId%3E%60%20instead%20of%20your%20intended%20callback.%20The%20correct%20behavior%20is%20to%20resolve%20RelayState%20as%20a%20verification%20ID%20and%20look%20up%20the%20stored%20callbackURL%20in%20the%20verification%20table%2C%20just%20like%20the%20SAML%20callback%20handler%20does.%20This%20bug%20is%20present%20in%20v1.4.18%20and%20no%20patch%20has%20been%20merged%20yet%20to%20fix%20it%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/583f12fb7db38681ee882d219ce3895faa4a6976/packages/sso/src/routes/sso.ts%23L2281-L2726%29%29.%0A%0AAs%20a%20workaround%20for%20404s%20in%20IdP-initiated%20flows%2C%20you%20can%20add%20explicit%20GET%20and%20POST%20handlers%20for%20your%20SAML%20callback%20route%2C%20but%20this%20does%20not%20fix%20the%20ACS%20handler%27s%20RelayState%20parsing%20bug%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/6615%23issuecomment-3638666970%29%29.%20Changing%20the%20callbackUrl%20is%20not%20a%20valid%20solution%2C%20as%20the%20SAML%20spec%20requires%20it%20to%20be%20the%20ACS%20URL%20%28%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/pull/6669%29%29.%0A%0AIf%20you%20need%20a%20temporary%20fix%2C%20you%20could%20monkey-patch%20the%20ACS%20handler%20to%20parse%20RelayState%20as%20a%20verification%20ID%20and%20fetch%20the%20stored%20callbackURL%2C%20similar%20to%20how%20%60parseRelayState%60%20is%20used%20in%20the%20callback%20handler.%20If%20you%20want%20a%20code%20example%20for%20this%20workaround%2C%20let%20me%20know.)&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/7777)
Author
Owner

@rbayliss commented on GitHub (Feb 3, 2026):

@dosu, yes, are you able to generate a temporary fix for the issue?

<!-- gh-comment-id:3843071906 --> @rbayliss commented on GitHub (Feb 3, 2026): @dosu, yes, are you able to generate a temporary fix for the issue?
Author
Owner

@dosubot[bot] commented on GitHub (Feb 3, 2026):

Here’s a temporary fix you can use to patch the SAML ACS handler so it correctly parses RelayState as a verification ID and redirects to the stored callbackURL, restoring SP-initiated SAML login flow.

// Place this in your project, e.g. `patch-saml-acs.ts`
import { parseRelayState } from "better-auth/dist/packages/sso/src/saml-state"; // Path may vary depending on your setup
import { acsEndpoint as originalAcsEndpoint } from "better-auth/dist/packages/sso/src/routes/sso";
import type { SSOOptions } from "better-auth/dist/packages/sso/src/types";

// Wrap the original ACS handler
export function patchedAcsEndpoint(options?: SSOOptions) {
  const handler = originalAcsEndpoint(options);
  return async (ctx: any) => {
    let relayStateObj: any = null;
    if (ctx.body?.RelayState) {
      try {
        relayStateObj = await parseRelayState(ctx);
      } catch (e) {
        ctx.context.logger?.warn?.("Failed to parse RelayState, falling back to default redirect", e);
      }
    }
    // Patch the redirect logic by monkey-patching ctx.redirect
    const origRedirect = ctx.redirect.bind(ctx);
    ctx.redirect = (url: string) => {
      if (
        relayStateObj &&
        relayStateObj.callbackURL &&
        (url === ctx.body.RelayState || url.endsWith("/" + ctx.body.RelayState))
      ) {
        return origRedirect(relayStateObj.callbackURL);
      }
      return origRedirect(url);
    };
    return handler(ctx);
  };
}

How to use it:

  • For Hono:

    import { Hono } from "hono";
    import { patchedAcsEndpoint } from "./patch-saml-acs";
    const app = new Hono();
    app.post("/sso/saml2/sp/acs/:providerId", patchedAcsEndpoint());
    
  • For Express:

    import express from "express";
    import { patchedAcsEndpoint } from "./patch-saml-acs";
    const app = express();
    app.post("/sso/saml2/sp/acs/:providerId", (req, res, next) => {
      patchedAcsEndpoint()(req, res, next);
    });
    
  • For custom routers, swap out your SSO ACS handler for patchedAcsEndpoint() in the same way.

This patch intercepts the redirect logic and, if RelayState is a verification ID, looks up the stored callbackURL and uses it for the redirect, mirroring the correct behavior in the SAML callback handler (reference). Remove this patch once an upstream fix is available.

Let me know if you need help adapting this for your specific framework or if you run into any issues!

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:3843125577 --> @dosubot[bot] commented on GitHub (Feb 3, 2026): <!-- Answer --> Here’s a temporary fix you can use to patch the SAML ACS handler so it correctly parses RelayState as a verification ID and redirects to the stored callbackURL, restoring SP-initiated SAML login flow. ```ts // Place this in your project, e.g. `patch-saml-acs.ts` import { parseRelayState } from "better-auth/dist/packages/sso/src/saml-state"; // Path may vary depending on your setup import { acsEndpoint as originalAcsEndpoint } from "better-auth/dist/packages/sso/src/routes/sso"; import type { SSOOptions } from "better-auth/dist/packages/sso/src/types"; // Wrap the original ACS handler export function patchedAcsEndpoint(options?: SSOOptions) { const handler = originalAcsEndpoint(options); return async (ctx: any) => { let relayStateObj: any = null; if (ctx.body?.RelayState) { try { relayStateObj = await parseRelayState(ctx); } catch (e) { ctx.context.logger?.warn?.("Failed to parse RelayState, falling back to default redirect", e); } } // Patch the redirect logic by monkey-patching ctx.redirect const origRedirect = ctx.redirect.bind(ctx); ctx.redirect = (url: string) => { if ( relayStateObj && relayStateObj.callbackURL && (url === ctx.body.RelayState || url.endsWith("/" + ctx.body.RelayState)) ) { return origRedirect(relayStateObj.callbackURL); } return origRedirect(url); }; return handler(ctx); }; } ``` **How to use it:** - For Hono: ```ts import { Hono } from "hono"; import { patchedAcsEndpoint } from "./patch-saml-acs"; const app = new Hono(); app.post("/sso/saml2/sp/acs/:providerId", patchedAcsEndpoint()); ``` - For Express: ```ts import express from "express"; import { patchedAcsEndpoint } from "./patch-saml-acs"; const app = express(); app.post("/sso/saml2/sp/acs/:providerId", (req, res, next) => { patchedAcsEndpoint()(req, res, next); }); ``` - For custom routers, swap out your SSO ACS handler for `patchedAcsEndpoint()` in the same way. This patch intercepts the redirect logic and, if RelayState is a verification ID, looks up the stored callbackURL and uses it for the redirect, mirroring the correct behavior in the SAML callback handler ([reference](https://github.com/better-auth/better-auth/blob/583f12fb7db38681ee882d219ce3895faa4a6976/packages/sso/src/routes/sso.ts#L56-L2726)). Remove this patch once an upstream fix is available. Let me know if you need help adapting this for your specific framework or if you run into any issues! <!-- 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/d2d3e9df-ef7d-428b-84a8-050c57bcd192?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d2d3e9df-ef7d-428b-84a8-050c57bcd192?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d2d3e9df-ef7d-428b-84a8-050c57bcd192?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d2d3e9df-ef7d-428b-84a8-050c57bcd192?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d2d3e9df-ef7d-428b-84a8-050c57bcd192?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d2d3e9df-ef7d-428b-84a8-050c57bcd192?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d2d3e9df-ef7d-428b-84a8-050c57bcd192?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=Here%E2%80%99s%20a%20temporary%20fix%20you%20can%20use%20to%20patch%20the%20SAML%20ACS%20handler%20so%20it%20correctly%20parses%20RelayState%20as%20a%20verification%20ID%20and%20redirects%20to%20the%20stored%20callbackURL%2C%20restoring%20SP-initiated%20SAML%20login%20flow.%0A%0A%60%60%60ts%0A//%20Place%20this%20in%20your%20project%2C%20e.g.%20%60patch-saml-acs.ts%60%0Aimport%20%7B%20parseRelayState%20%7D%20from%20%22better-auth/dist/packages/sso/src/saml-state%22%3B%20//%20Path%20may%20vary%20depending%20on%20your%20setup%0Aimport%20%7B%20acsEndpoint%20as%20originalAcsEndpoint%20%7D%20from%20%22better-auth/dist/packages/sso/src/routes/sso%22%3B%0Aimport%20type%20%7B%20SSOOptions%20%7D%20from%20%22better-auth/dist/packages/sso/src/types%22%3B%0A%0A//%20Wrap%20the%20original%20ACS%20handler%0Aexport%20function%20patchedAcsEndpoint%28options%3F%3A%20SSOOptions%29%20%7B%0A%20%20const%20handler%20%3D%20originalAcsEndpoint%28options%29%3B%0A%20%20return%20async%20%28ctx%3A%20any%29%20%3D%3E%20%7B%0A%20%20%20%20let%20relayStateObj%3A%20any%20%3D%20null%3B%0A%20%20%20%20if%20%28ctx.body%3F.RelayState%29%20%7B%0A%20%20%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20relayStateObj%20%3D%20await%20parseRelayState%28ctx%29%3B%0A%20%20%20%20%20%20%7D%20catch%20%28e%29%20%7B%0A%20%20%20%20%20%20%20%20ctx.context.logger%3F.warn%3F.%28%22Failed%20to%20parse%20RelayState%2C%20falling%20back%20to%20default%20redirect%22%2C%20e%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20//%20Patch%20the%20redirect%20logic%20by%20monkey-patching%20ctx.redirect%0A%20%20%20%20const%20origRedirect%20%3D%20ctx.redirect.bind%28ctx%29%3B%0A%20%20%20%20ctx.redirect%20%3D%20%28url%3A%20string%29%20%3D%3E%20%7B%0A%20%20%20%20%20%20if%20%28%0A%20%20%20%20%20%20%20%20relayStateObj%20%26%26%0A%20%20%20%20%20%20%20%20relayStateObj.callbackURL%20%26%26%0A%20%20%20%20%20%20%20%20%28url%20%3D%3D%3D%20ctx.body.RelayState%20%7C%7C%20url.endsWith%28%22/%22%20%2B%20ctx.body.RelayState%29%29%0A%20%20%20%20%20%20%29%20%7B%0A%20%20%20%20%20%20%20%20return%20origRedirect%28relayStateObj.callbackURL%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20origRedirect%28url%29%3B%0A%20%20%20%20%7D%3B%0A%20%20%20%20return%20handler%28ctx%29%3B%0A%20%20%7D%3B%0A%7D%0A%60%60%60%0A%0A%2A%2AHow%20to%20use%20it%3A%2A%2A%0A%0A-%20For%20Hono%3A%0A%20%20%60%60%60ts%0A%20%20import%20%7B%20Hono%20%7D%20from%20%22hono%22%3B%0A%20%20import%20%7B%20patchedAcsEndpoint%20%7D%20from%20%22./patch-saml-acs%22%3B%0A%20%20const%20app%20%3D%20new%20Hono%28%29%3B%0A%20%20app.post%28%22/sso/saml2/sp/acs/%3AproviderId%22%2C%20patchedAcsEndpoint%28%29%29%3B%0A%20%20%60%60%60%0A%0A-%20For%20Express%3A%0A%20%20%60%60%60ts%0A%20%20import%20express%20from%20%22express%22%3B%0A%20%20import%20%7B%20patchedAcsEndpoint%20%7D%20from%20%22./patch-saml-acs%22%3B%0A%20%20const%20app%20%3D%20express%28%29%3B%0A%20%20app.post%28%22/sso/saml2/sp/acs/%3AproviderId%22%2C%20%28req%2C%20res%2C%20next%29%20%3D%3E%20%7B%0A%20%20%20%20patchedAcsEndpoint%28%29%28req%2C%20res%2C%20next%29%3B%0A%20%20%7D%29%3B%0A%20%20%60%60%60%0A%0A-%20For%20custom%20routers%2C%20swap%20out%20your%20SSO%20ACS%20handler%20for%20%60patchedAcsEndpoint%28%29%60%20in%20the%20same%20way.%0A%0AThis%20patch%20intercepts%20the%20redirect%20logic%20and%2C%20if%20RelayState%20is%20a%20verification%20ID%2C%20looks%20up%20the%20stored%20callbackURL%20and%20uses%20it%20for%20the%20redirect%2C%20mirroring%20the%20correct%20behavior%20in%20the%20SAML%20callback%20handler%20%28%5Breference%5D%28https%3A//github.com/better-auth/better-auth/blob/583f12fb7db38681ee882d219ce3895faa4a6976/packages/sso/src/routes/sso.ts%23L56-L2726%29%29.%20Remove%20this%20patch%20once%20an%20upstream%20fix%20is%20available.%0A%0ALet%20me%20know%20if%20you%20need%20help%20adapting%20this%20for%20your%20specific%20framework%20or%20if%20you%20run%20into%20any%20issues%21)&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/7777)
Author
Owner

@bytaesu commented on GitHub (Feb 4, 2026):

@Paola3stefania Could you look into this? 🙏

<!-- gh-comment-id:3845579929 --> @bytaesu commented on GitHub (Feb 4, 2026): @Paola3stefania Could you look into this? 🙏
Author
Owner

@rbayliss commented on GitHub (Feb 4, 2026):

I've proposed a fix in https://github.com/better-auth/better-auth/pull/7781.

<!-- gh-comment-id:3847583909 --> @rbayliss commented on GitHub (Feb 4, 2026): I've proposed a fix in https://github.com/better-auth/better-auth/pull/7781.
Author
Owner

@Paola3stefania commented on GitHub (Feb 4, 2026):

Hi, thank you @rbayliss would look into this

<!-- gh-comment-id:3850230979 --> @Paola3stefania commented on GitHub (Feb 4, 2026): Hi, thank you @rbayliss would look into this
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#28224