[GH-ISSUE #3882] Sessions not deleted properly when deleting user #18384

Closed
opened 2026-04-15 16:50:40 -05:00 by GiteaMirror · 7 comments
Owner

Originally created by @DevDuki on GitHub (Aug 8, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3882

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create a user
  2. open 2 browser and log in with the same user
  3. delete the user in one browser
  4. the user in the other browser still has an active session

Current vs. Expected behavior

When a user has multiple active sessions, only the the session where the deletion happened one gets deleted. The others still remain active.

I expect all sessions to be deleted

What version of Better Auth are you using?

1.3.4

Provide environment information

- MacOS: Sequoia 15.6

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

Backend

Auth config (if applicable)

export const auth = betterAuth({
    // Used as issuer for 2FA
    appName: 'Test',

    // Session
    session: {
        expiresIn: SESSION_EXPIRES_IN
    },

    // Database
    database: prismaAdapter(prisma, {
        provider: 'sqlite'
    }),

    // Cookies
    advanced: {
        cookiePrefix: 'recipe'
    },

    // Email/Password
    emailAndPassword: {
        enabled: true,
        sendResetPassword: async ({ user, url }, request) => { ... }
    },
    emailVerification: {
        sendOnSignUp: true,
        autoSignInAfterVerification: true,
        sendVerificationEmail: async ({ user, url }, request) => { ... }
    },

    // User
    user: {
        additionalFields: { ... },
        changeEmail: {
            enabled: true,
            sendChangeEmailVerification: async ({ user, url }, request) => { ... }
        },
        deleteUser: {
            enabled: true,
            sendDeleteAccountVerification: async ({ user, url }, request) => { ... }
        }
    },

    // Socials
    socialProviders: { ... },

    // Plugins
    plugins: [
        twoFactor(),
        passkey(),
        stripePlugin,
        refreshUserInSessionPlugin,
        accountDependenciesCleanupPlugin,
        sveltekitCookies(getRequestEvent) // <= Must be the last plugin!
    ],

    // Redis
    secondaryStorage: {
        get: async (key) => {
            const value = await redis.get(REDIS_PREFIX + key);
            return value ? value : null;
        },
        set: async (key, value, ttl) => {
            if (ttl) await redis.set(REDIS_PREFIX + key, value, { EX: ttl });
            else await redis.set(REDIS_PREFIX + key, value);
        },
        delete: async (key) => {
            await redis.del(REDIS_PREFIX + key);
        }
    }
});

Additional context

https://discord.com/channels/1288403910284935179/1403382349718229022

Originally created by @DevDuki on GitHub (Aug 8, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3882 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create a user 2. open 2 browser and log in with the same user 3. delete the user in one browser 4. the user in the other browser still has an active session ### Current vs. Expected behavior When a user has multiple active sessions, only the the session where the deletion happened one gets deleted. The others still remain active. I expect all sessions to be deleted ### What version of Better Auth are you using? 1.3.4 ### Provide environment information ```bash - MacOS: Sequoia 15.6 ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript export const auth = betterAuth({ // Used as issuer for 2FA appName: 'Test', // Session session: { expiresIn: SESSION_EXPIRES_IN }, // Database database: prismaAdapter(prisma, { provider: 'sqlite' }), // Cookies advanced: { cookiePrefix: 'recipe' }, // Email/Password emailAndPassword: { enabled: true, sendResetPassword: async ({ user, url }, request) => { ... } }, emailVerification: { sendOnSignUp: true, autoSignInAfterVerification: true, sendVerificationEmail: async ({ user, url }, request) => { ... } }, // User user: { additionalFields: { ... }, changeEmail: { enabled: true, sendChangeEmailVerification: async ({ user, url }, request) => { ... } }, deleteUser: { enabled: true, sendDeleteAccountVerification: async ({ user, url }, request) => { ... } } }, // Socials socialProviders: { ... }, // Plugins plugins: [ twoFactor(), passkey(), stripePlugin, refreshUserInSessionPlugin, accountDependenciesCleanupPlugin, sveltekitCookies(getRequestEvent) // <= Must be the last plugin! ], // Redis secondaryStorage: { get: async (key) => { const value = await redis.get(REDIS_PREFIX + key); return value ? value : null; }, set: async (key, value, ttl) => { if (ttl) await redis.set(REDIS_PREFIX + key, value, { EX: ttl }); else await redis.set(REDIS_PREFIX + key, value); }, delete: async (key) => { await redis.del(REDIS_PREFIX + key); } } }); ``` ### Additional context https://discord.com/channels/1288403910284935179/1403382349718229022
GiteaMirror added the lockedbug labels 2026-04-15 16:50:41 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 8, 2025):

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

This is a known bug in Better Auth v1.3.4 when using Redis as secondary storage: deleting a user should remove all their sessions, but stale session tokens can remain in the active-sessions-{userId} list, leaving other browsers/devices logged in until expiration. This happens because the session deletion logic doesn't fully clean up the Redis records for all sessions in that list [source].

Recent updates have fixed this in newer versions—session deletion now properly removes tokens from both the session and user-based secondary storage [source].

If you can't upgrade yet, you can work around this by adding a custom hook to your Better Auth config that manually deletes all session tokens from active-sessions-{userId} in Redis when a user is deleted. Here’s a TypeScript example for an afterDelete hook:

user: {
  deleteUser: {
    enabled: true,
    afterDelete: async (user) => {
      const key = `active-sessions-${user.id}`;
      const listRaw = await redis.get(key);
      if (!listRaw) return;
      const list = JSON.parse(listRaw);
      for (const session of list) {
        await redis.del(session.token);
      }
      await redis.del(key);
    }
  }
}

This ensures all sessions for the deleted user are removed immediately. If you upgrade to the latest Better Auth, this workaround shouldn’t be necessary.

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:3168327940 --> @dosubot[bot] commented on GitHub (Aug 8, 2025): <!-- Greeting --> Hi @DevDuki! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known bug in Better Auth v1.3.4 when using Redis as secondary storage: deleting a user should remove all their sessions, but stale session tokens can remain in the `active-sessions-{userId}` list, leaving other browsers/devices logged in until expiration. This happens because the session deletion logic doesn't fully clean up the Redis records for all sessions in that list [[source](https://github.com/better-auth/better-auth/issues/3819)]. Recent updates have fixed this in newer versions—session deletion now properly removes tokens from both the session and user-based secondary storage [[source](https://github.com/better-auth/better-auth/pull/3820)]. If you can't upgrade yet, you can work around this by adding a custom hook to your Better Auth config that manually deletes all session tokens from `active-sessions-{userId}` in Redis when a user is deleted. Here’s a TypeScript example for an `afterDelete` hook: ```typescript user: { deleteUser: { enabled: true, afterDelete: async (user) => { const key = `active-sessions-${user.id}`; const listRaw = await redis.get(key); if (!listRaw) return; const list = JSON.parse(listRaw); for (const session of list) { await redis.del(session.token); } await redis.del(key); } } } ``` This ensures all sessions for the deleted user are removed immediately. If you upgrade to the latest Better Auth, this workaround shouldn’t be necessary. <!-- 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/d71a2a6e-5c56-49e0-a221-45c17235cb8e?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d71a2a6e-5c56-49e0-a221-45c17235cb8e?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d71a2a6e-5c56-49e0-a221-45c17235cb8e?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d71a2a6e-5c56-49e0-a221-45c17235cb8e?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d71a2a6e-5c56-49e0-a221-45c17235cb8e?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d71a2a6e-5c56-49e0-a221-45c17235cb8e?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d71a2a6e-5c56-49e0-a221-45c17235cb8e?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/3882)
Author
Owner

@DevDuki commented on GitHub (Nov 17, 2025):

@dosu please do not close this issue, since a PR is still open that fixes this issue. Thanks you

<!-- gh-comment-id:3540107302 --> @DevDuki commented on GitHub (Nov 17, 2025): @dosu please do not close this issue, since a PR is still open that fixes this issue. Thanks you
Author
Owner

@dosubot[bot] commented on GitHub (Nov 17, 2025):

Understood—no action will be taken to close this issue while the related PR is still open. If you want updates or status checks on the PR, just let me know.

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:3540108112 --> @dosubot[bot] commented on GitHub (Nov 17, 2025): <!-- Answer --> Understood—no action will be taken to close this issue while the related PR is still open. If you want updates or status checks on the PR, just 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/c7f234f4-f271-44df-8059-4d45d4ee8200?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/c7f234f4-f271-44df-8059-4d45d4ee8200?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/c7f234f4-f271-44df-8059-4d45d4ee8200?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/c7f234f4-f271-44df-8059-4d45d4ee8200?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/c7f234f4-f271-44df-8059-4d45d4ee8200?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/c7f234f4-f271-44df-8059-4d45d4ee8200?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/c7f234f4-f271-44df-8059-4d45d4ee8200?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/3882)
Author
Owner

@DevDuki commented on GitHub (Nov 17, 2025):

@dosu can you please reopen this issue then? You closed it 3 days ago

<!-- gh-comment-id:3540109540 --> @DevDuki commented on GitHub (Nov 17, 2025): @dosu can you please reopen this issue then? You closed it 3 days ago
Author
Owner

@dosubot[bot] commented on GitHub (Nov 17, 2025):

I don't have the ability to directly reopen GitHub issues. Only repository maintainers or users with the right permissions can do that. To keep the issue open until the PR is merged, someone with access will need to manually reopen it. If you need updates on the PR or anything else, just let me know!

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:3540110702 --> @dosubot[bot] commented on GitHub (Nov 17, 2025): <!-- Answer --> I don't have the ability to directly reopen GitHub issues. Only repository maintainers or users with the right permissions can do that. To keep the issue open until the PR is merged, someone with access will need to manually reopen it. If you need updates on the PR or anything else, just 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/fa77b13b-ab52-44cd-b96c-d6365b462b2f?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/fa77b13b-ab52-44cd-b96c-d6365b462b2f?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/fa77b13b-ab52-44cd-b96c-d6365b462b2f?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/fa77b13b-ab52-44cd-b96c-d6365b462b2f?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/fa77b13b-ab52-44cd-b96c-d6365b462b2f?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/fa77b13b-ab52-44cd-b96c-d6365b462b2f?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/fa77b13b-ab52-44cd-b96c-d6365b462b2f?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/3882)
Author
Owner

@dosubot[bot] commented on GitHub (Nov 17, 2025):

@Bekacru, the user @DevDuki has pointed out that this issue should remain open as there is still a PR addressing it. Could you please take a look and assist?

<!-- gh-comment-id:3540111919 --> @dosubot[bot] commented on GitHub (Nov 17, 2025): @Bekacru, the user @DevDuki has pointed out that this issue should remain open as there is still a PR addressing it. Could you please take a look and assist?
Author
Owner

@dosubot[bot] commented on GitHub (Nov 17, 2025):

@Bekacru, the user @DevDuki has requested to reopen the issue that was closed 3 days ago. Could you please take a look and assist?

<!-- gh-comment-id:3540115295 --> @dosubot[bot] commented on GitHub (Nov 17, 2025): @Bekacru, the user @DevDuki has requested to reopen the issue that was closed 3 days ago. Could you please take a look and assist?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#18384