[GH-ISSUE #5266] Anonymous pugin doesn't return session #10198

Closed
opened 2026-04-13 06:10:54 -05:00 by GiteaMirror · 10 comments
Owner

Originally created by @Aft1n on GitHub (Oct 13, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/5266

Hello, thanks for creating such a nice library for auth.

I'm not sure if this is an issue with the library or my understanding, so maybe someone can help me.

I'm using anonymous plugin to register users automatically at first, they register just fine, i can see user created, but i never can get their session later on.

In my nuxt app neither auth-client nor auth.api on the server returns me session, i have tried to set different cookie names, but nothing helps, i can easily get session for normal signed in account, but not anonymous.

Is it how it is intended to work or is there a bug, because if its just how it was designed, then how can i create any posts or cart items inside db, if i dont even get the user.id?

thanks

Originally created by @Aft1n on GitHub (Oct 13, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/5266 Hello, thanks for creating such a nice library for auth. I'm not sure if this is an issue with the library or my understanding, so maybe someone can help me. I'm using anonymous plugin to register users automatically at first, they register just fine, i can see user created, but i never can get their session later on. In my nuxt app neither auth-client nor auth.api on the server returns me session, i have tried to set different cookie names, but nothing helps, i can easily get session for normal signed in account, but not anonymous. Is it how it is intended to work or is there a bug, because if its just how it was designed, then how can i create any posts or cart items inside db, if i dont even get the user.id? thanks
GiteaMirror added the lockedbug labels 2026-04-13 06:10:54 -05:00
Author
Owner

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

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

Sessions for anonymous users are supposed to be created and retrievable, but there’s a known bug in the anonymous plugin’s after hook that can block the session from being returned on the initial sign-in. The bug happens because the hook doesn’t distinguish between a session just created in the current request and one that already existed, so it sometimes rejects the request even though the user and session were created. This means you might only get the session after a page reload, not immediately after registration [details].

To work around this, you can modify the plugin’s after hook to check for ctx.context.newSession before throwing the error. If you’re using Nuxt, also make sure you’re handling cookies in client components or server actions, since server components can’t set cookies and that can cause the browser to be out of sync with the session [discussion].

For creating posts or cart items, you need to use the existing anonymous session and its user.id. If you’re not getting the session, try fetching it manually from /api/auth/get-session or ensure your sign-in flow is happening in a client context where cookies are set. If you want to upgrade the anonymous user to a full account, use account linking—this is the recommended approach and is handled automatically when the user authenticates with a provider [docs].

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:3396136706 --> @dosubot[bot] commented on GitHub (Oct 13, 2025): <!-- Greeting --> Hi @Aft1n! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> Sessions for anonymous users are supposed to be created and retrievable, but there’s a known bug in the anonymous plugin’s `after` hook that can block the session from being returned on the initial sign-in. The bug happens because the hook doesn’t distinguish between a session just created in the current request and one that already existed, so it sometimes rejects the request even though the user and session were created. This means you might only get the session after a page reload, not immediately after registration [[details](https://github.com/better-auth/better-auth/issues/3658)]. To work around this, you can modify the plugin’s `after` hook to check for `ctx.context.newSession` before throwing the error. If you’re using Nuxt, also make sure you’re handling cookies in client components or server actions, since server components can’t set cookies and that can cause the browser to be out of sync with the session [[discussion](https://github.com/better-auth/better-auth/issues/2055)]. For creating posts or cart items, you need to use the existing anonymous session and its `user.id`. If you’re not getting the session, try fetching it manually from `/api/auth/get-session` or ensure your sign-in flow is happening in a client context where cookies are set. If you want to upgrade the anonymous user to a full account, use account linking—this is the recommended approach and is handled automatically when the user authenticates with a provider [[docs](https://github.com/better-auth/better-auth/issues/3267)]. <!-- 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/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/81fbbff2-9f14-48ea-8c0d-4bfaf4f0b9f9?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/5266)
Author
Owner

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

Yeah, i dont think that's an issue with oage reload.. im receiving the token, in server endpoint i set it with setCookie() and it has the same structure as better-auth set token, so basically identical cookies for authenticated user i can getSession() both on client and server passing headers, and with anonymous() it just throws errors, even after multiple page reloads

<!-- gh-comment-id:3396266218 --> @Aft1n commented on GitHub (Oct 13, 2025): Yeah, i dont think that's an issue with oage reload.. im receiving the token, in server endpoint i set it with setCookie() and it has the same structure as better-auth set token, so basically identical cookies for authenticated user i can getSession() both on client and server passing headers, and with anonymous() it just throws errors, even after multiple page reloads
Author
Owner

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

This isn't expected behavior—anonymous sessions should be retrievable just like authenticated ones if the cookies are set correctly. The most likely cause is a bug in the anonymous plugin's after hook: it sometimes throws a "Anonymous users cannot sign in again anonymously" error if it can't detect that a new session was just created, even if the session and cookies are valid. This can happen if ctx.context.newSession isn't set during the request, which can occur with custom flows or manual cookie handling [plugin code].

Since you confirmed the cookie structure matches and getSession() works for authenticated users, the issue is almost certainly in the backend validation logic for anonymous sessions, not in the cookies themselves. To work around this, you can patch the after hook to check for ctx.context.newSession before throwing the error, or ensure your sign-in flow sets this context correctly. If you’re using a custom server endpoint, double-check that the session is actually created in the database and that the session token matches what getSession() expects.

If you can share the exact error message from getSession(), that might help pinpoint whether it's this known bug or something else.

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:3396279640 --> @dosubot[bot] commented on GitHub (Oct 13, 2025): <!-- Answer --> This isn't expected behavior—anonymous sessions should be retrievable just like authenticated ones if the cookies are set correctly. The most likely cause is a bug in the anonymous plugin's after hook: it sometimes throws a "Anonymous users cannot sign in again anonymously" error if it can't detect that a new session was just created, even if the session and cookies are valid. This can happen if ctx.context.newSession isn't set during the request, which can occur with custom flows or manual cookie handling [[plugin code](https://github.com/better-auth/better-auth/blob/f4a91d090004d1c24c7d3fa8e7ac8302f249c3e5/packages/better-auth/src/plugins/anonymous/index.ts)]. Since you confirmed the cookie structure matches and getSession() works for authenticated users, the issue is almost certainly in the backend validation logic for anonymous sessions, not in the cookies themselves. To work around this, you can patch the after hook to check for ctx.context.newSession before throwing the error, or ensure your sign-in flow sets this context correctly. If you’re using a custom server endpoint, double-check that the session is actually created in the database and that the session token matches what getSession() expects. If you can share the exact error message from getSession(), that might help pinpoint whether it's this known bug or something else. <!-- 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/6d88e457-c5b0-4899-b118-209d5a599483?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/6d88e457-c5b0-4899-b118-209d5a599483?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/6d88e457-c5b0-4899-b118-209d5a599483?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/6d88e457-c5b0-4899-b118-209d5a599483?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/6d88e457-c5b0-4899-b118-209d5a599483?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/6d88e457-c5b0-4899-b118-209d5a599483?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/6d88e457-c5b0-4899-b118-209d5a599483?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/5266)
Author
Owner

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

Ok, so the issue was with signinAnonymous() returning a token, but it is not a cookie to be set for user, so when i have set asResponse: true it returned the correct full session_toke, and i was able to get session both in client and server..

Though the question is how can received token from signinAnonymous() can be exchanged for complete cookie header to set it up in user cookies and not set asResponse flag?

<!-- gh-comment-id:3396688852 --> @Aft1n commented on GitHub (Oct 13, 2025): Ok, so the issue was with signinAnonymous() returning a token, but it is not a cookie to be set for user, so when i have set asResponse: true it returned the correct full session_toke, and i was able to get session both in client and server.. Though the question is how can received token from signinAnonymous() can be exchanged for complete cookie header to set it up in user cookies and not set asResponse flag?
Author
Owner

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

There isn’t a built-in Better Auth helper to turn the token from signinAnonymous() into a full Set-Cookie header for manual use. Internally, the session cookie is set using backend context utilities that handle signing, naming, and attributes like secure, httpOnly, sameSite, and path [code reference].

If you need to set the cookie manually, you’ll have to replicate the internal logic: use the correct cookie name (usually __Secure-better-auth.session_token if secure cookies are enabled), set the value to the token, and include attributes like Path=/; HttpOnly; Secure; SameSite=Lax. However, if your setup uses signed cookies or custom attributes, you’ll need to match those exactly, or session validation may fail [cookie logic].

Here’s a basic example for manual cookie setting (assuming no signing):

// Example for server-side (Node/Express)
res.setHeader('Set-Cookie', [
  `__Secure-better-auth.session_token=${token}; Path=/; HttpOnly; Secure; SameSite=Lax`
]);

If your Better Auth config uses a different cookie name or domain, adjust accordingly. For production, always ensure you match the security attributes and signing requirements used by your backend.

Manual cookie construction is not officially documented and may break if your config changes or if Better Auth updates its internal logic. The recommended approach is to use asResponse: true or let Better Auth handle cookie setting via its API.

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:3396702912 --> @dosubot[bot] commented on GitHub (Oct 13, 2025): <!-- Answer --> There isn’t a built-in Better Auth helper to turn the token from signinAnonymous() into a full Set-Cookie header for manual use. Internally, the session cookie is set using backend context utilities that handle signing, naming, and attributes like secure, httpOnly, sameSite, and path [[code reference](https://github.com/better-auth/better-auth/blob/f4a91d090004d1c24c7d3fa8e7ac8302f249c3e5/packages/better-auth/src/plugins/anonymous/index.ts)]. If you need to set the cookie manually, you’ll have to replicate the internal logic: use the correct cookie name (usually `__Secure-better-auth.session_token` if secure cookies are enabled), set the value to the token, and include attributes like `Path=/; HttpOnly; Secure; SameSite=Lax`. However, if your setup uses signed cookies or custom attributes, you’ll need to match those exactly, or session validation may fail [[cookie logic](https://github.com/better-auth/better-auth/blob/f4a91d090004d1c24c7d3fa8e7ac8302f249c3e5/packages/better-auth/src/cookies/index.ts)]. Here’s a basic example for manual cookie setting (assuming no signing): ```js // Example for server-side (Node/Express) res.setHeader('Set-Cookie', [ `__Secure-better-auth.session_token=${token}; Path=/; HttpOnly; Secure; SameSite=Lax` ]); ``` If your Better Auth config uses a different cookie name or domain, adjust accordingly. For production, always ensure you match the security attributes and signing requirements used by your backend. Manual cookie construction is not officially documented and may break if your config changes or if Better Auth updates its internal logic. The recommended approach is to use asResponse: true or let Better Auth handle cookie setting via its API. <!-- 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/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/0cf8e8fa-64b3-4ad9-991e-e1023025ce8e?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/5266)
Author
Owner

@ping-maxwell commented on GitHub (Oct 13, 2025):

I noticed you're using signinAnonymous, so I assume you're using auth.api on a server enviroment?

<!-- gh-comment-id:3397702843 --> @ping-maxwell commented on GitHub (Oct 13, 2025): I noticed you're using `signinAnonymous`, so I assume you're using auth.api on a server enviroment?
Author
Owner

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

Yes, the problem was that it was returning not the full cookie, that i could just pass to the client.. Anyway setting asResponse to true returned me the correct cookie, and now it works

<!-- gh-comment-id:3397757964 --> @Aft1n commented on GitHub (Oct 13, 2025): Yes, the problem was that it was returning not the full cookie, that i could just pass to the client.. Anyway setting asResponse to true returned me the correct cookie, and now it works
Author
Owner

@ping-maxwell commented on GitHub (Oct 13, 2025):

@Aft1n Just to confirm, is this a bug on Better-Auth's side? or just a matter of requiring custom implementation in order for cookies to work in your context

<!-- gh-comment-id:3398171311 --> @ping-maxwell commented on GitHub (Oct 13, 2025): @Aft1n Just to confirm, is this a bug on Better-Auth's side? or just a matter of requiring custom implementation in order for cookies to work in your context
Author
Owner

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

@ping-maxwell i assume better-auth works as expected, the only question might be with anonymous plugin and the token it returns, from what bot has replied that there is no way to get cookie with that short token

basically or im missing the purpose of this not full-length token, or anonymous signin must return the full-length token that can be easily set as cookie

<!-- gh-comment-id:3398191267 --> @Aft1n commented on GitHub (Oct 13, 2025): @ping-maxwell i assume better-auth works as expected, the only question might be with anonymous plugin and the token it returns, from what bot has replied that there is no way to get cookie with that short token basically or im missing the purpose of this not full-length token, or anonymous signin must return the full-length token that can be easily set as cookie
Author
Owner

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

Cookies are signed by default but the token that's returned from anonymous or any other endpoint isn't signed. If you need to get the signed cookie value, you'd need to provide asResposne or returnHeaders

<!-- gh-comment-id:3398516254 --> @Bekacru commented on GitHub (Oct 13, 2025): Cookies are signed by default but the token that's returned from anonymous or any other endpoint isn't signed. If you need to get the signed cookie value, you'd need to provide `asResposne` or `returnHeaders`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10198