signUpEmail doesn't throw error when duplicate email caught #3016

Open
opened 2026-03-13 10:34:35 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @mdarkanurl on GitHub (Mar 7, 2026).

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create a sign-up function where I use the signUpEmail API.
  2. Previously, the signUpEmail API threw an error when it encountered a duplicate email.
  3. However, with @thallesp/nestjs-better-auth ^2.4.0 and better-auth ^1.4.20, it no longer throws an error for duplicate emails.

Current vs. Expected behavior

Image

I created a sign-up function using the signUpEmail API.
Before, it threw an error if the email already existed.
With @thallesp/nestjs-better-auth ^2.4.0 and better-auth ^1.4.20, it no longer throws that duplicate email error.

What version of Better Auth are you using?

^1.4.20

System info

{
  "system": {
    "platform": "win32",
    "arch": "x64",
    "version": "Windows 11 Pro",
    "release": "10.0.26200",
    "cpuCount": 16,
    "cpuModel": "AMD Ryzen 7 5700G with Radeon Graphics         ",
    "totalMemory": "7.40 GB",
    "freeMemory": "1.00 GB"
  },
  "node": {
    "version": "v22.20.0",
    "env": "development"
  },
  "packageManager": {
    "name": "npm",
    "version": "10.9.3"
  },
  "frameworks": null,
  "databases": [
    {
      "name": "pg",
      "version": "^8.19.0"
    },
    {
      "name": "@prisma/client",
      "version": "^7.4.2"
    }
  ],
  "betterAuth": {
    "version": "^1.4.20",
    "config": {
      "url": "http://localhost:3000",
      "secret": "[REDACTED]",
      "emailAndPassword": {
        "enabled": true,
        "requireEmailVerification": true,
        "resetPasswordTokenExpiresIn": 300,
        "revokeSessionsOnPasswordReset": true
      },
      "emailVerification": {
        "autoSignInAfterVerification": true,
        "sendOnSignUp": true,
        "expiresIn": 300
      },
      "rateLimit": {
        "enabled": true,
        "window": 60,
        "max": 100,
        "customRules": {
          "/sign-in/email": {
            "window": 10,
            "max": 3
          },
          "/sign-up/email": {
            "window": 10,
            "max": 3
          }
        }
      },
      "advanced": {
        "ipAddress": {
          "ipAddressHeaders": [
            "x-forwarded-for",
            "cf-connecting-ip"
          ]
        }
      },
      "trustedOrigins": [
        "http://localhost:3000"
      ]
    }
  }
}

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

No response

Originally created by @mdarkanurl on GitHub (Mar 7, 2026). ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create a sign-up function where I use the signUpEmail API. 2. Previously, the signUpEmail API threw an error when it encountered a duplicate email. 3. However, with @thallesp/nestjs-better-auth ^2.4.0 and better-auth ^1.4.20, it no longer throws an error for duplicate emails. ### Current vs. Expected behavior <img width="695" height="519" alt="Image" src="https://github.com/user-attachments/assets/3c253cde-3ae6-4f64-89ea-7ab75db289c9" /> I created a sign-up function using the signUpEmail API. Before, it threw an error if the email already existed. With @thallesp/nestjs-better-auth ^2.4.0 and better-auth ^1.4.20, it no longer throws that duplicate email error. ### What version of Better Auth are you using? ^1.4.20 ### System info ```bash { "system": { "platform": "win32", "arch": "x64", "version": "Windows 11 Pro", "release": "10.0.26200", "cpuCount": 16, "cpuModel": "AMD Ryzen 7 5700G with Radeon Graphics ", "totalMemory": "7.40 GB", "freeMemory": "1.00 GB" }, "node": { "version": "v22.20.0", "env": "development" }, "packageManager": { "name": "npm", "version": "10.9.3" }, "frameworks": null, "databases": [ { "name": "pg", "version": "^8.19.0" }, { "name": "@prisma/client", "version": "^7.4.2" } ], "betterAuth": { "version": "^1.4.20", "config": { "url": "http://localhost:3000", "secret": "[REDACTED]", "emailAndPassword": { "enabled": true, "requireEmailVerification": true, "resetPasswordTokenExpiresIn": 300, "revokeSessionsOnPasswordReset": true }, "emailVerification": { "autoSignInAfterVerification": true, "sendOnSignUp": true, "expiresIn": 300 }, "rateLimit": { "enabled": true, "window": 60, "max": 100, "customRules": { "/sign-in/email": { "window": 10, "max": 3 }, "/sign-up/email": { "window": 10, "max": 3 } } }, "advanced": { "ipAddress": { "ipAddressHeaders": [ "x-forwarded-for", "cf-connecting-ip" ] } }, "trustedOrigins": [ "http://localhost:3000" ] } } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context _No response_
GiteaMirror added the bug label 2026-03-13 10:34:35 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Mar 7, 2026):

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

This is expected behavior starting from better-auth v1.5.2, introduced in PR #8091 to prevent user enumeration attacks.

Since your config has requireEmailVerification: true, the signUpEmail endpoint now returns a 200 OK with a synthetic user object instead of throwing an error for duplicate emails. This prevents attackers from discovering which emails are registered.

To detect duplicate sign-ups, use the new onExistingUserSignUp callback:

emailAndPassword: {
  enabled: true,
  requireEmailVerification: true,
  onExistingUserSignUp: async ({ user }, request) => {
    // Handle duplicate sign-up attempt here
    console.log(`Duplicate sign-up attempt for: ${user.email}`);
  },
}

To restore the old error-throwing behavior (not recommended for security reasons), set autoSignIn: true AND requireEmailVerification: false.

Related issue: #8363 discusses this same behavior change.

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

@dosubot[bot] commented on GitHub (Mar 7, 2026): <!-- Greeting --> Hi @mdarkanurl! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is **expected behavior** starting from better-auth v1.5.2, introduced in [PR #8091](https://github.com/better-auth/better-auth/pull/8091) to prevent user enumeration attacks. Since your config has `requireEmailVerification: true`, the `signUpEmail` endpoint now returns a 200 OK with a synthetic user object instead of throwing an error for duplicate emails. This prevents attackers from discovering which emails are registered. **To detect duplicate sign-ups**, use the new `onExistingUserSignUp` callback: ```typescript emailAndPassword: { enabled: true, requireEmailVerification: true, onExistingUserSignUp: async ({ user }, request) => { // Handle duplicate sign-up attempt here console.log(`Duplicate sign-up attempt for: ${user.email}`); }, } ``` **To restore the old error-throwing behavior** (not recommended for security reasons), set `autoSignIn: true` AND `requireEmailVerification: false`. Related issue: [#8363](https://github.com/better-auth/better-auth/issues/8363) discusses this same behavior change. <!-- 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/69c775cd-c749-44bf-80c9-3af9b1d7618c?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/69c775cd-c749-44bf-80c9-3af9b1d7618c?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/69c775cd-c749-44bf-80c9-3af9b1d7618c?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/69c775cd-c749-44bf-80c9-3af9b1d7618c?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/69c775cd-c749-44bf-80c9-3af9b1d7618c?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/69c775cd-c749-44bf-80c9-3af9b1d7618c?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/69c775cd-c749-44bf-80c9-3af9b1d7618c?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%20%2A%2Aexpected%20behavior%2A%2A%20starting%20from%20better-auth%20v1.5.2%2C%20introduced%20in%20%5BPR%20%238091%5D%28https%3A//github.com/better-auth/better-auth/pull/8091%29%20to%20prevent%20user%20enumeration%20attacks.%0A%0ASince%20your%20config%20has%20%60requireEmailVerification%3A%20true%60%2C%20the%20%60signUpEmail%60%20endpoint%20now%20returns%20a%20200%20OK%20with%20a%20synthetic%20user%20object%20instead%20of%20throwing%20an%20error%20for%20duplicate%20emails.%20This%20prevents%20attackers%20from%20discovering%20which%20emails%20are%20registered.%0A%0A%2A%2ATo%20detect%20duplicate%20sign-ups%2A%2A%2C%20use%20the%20new%20%60onExistingUserSignUp%60%20callback%3A%0A%0A%60%60%60typescript%0AemailAndPassword%3A%20%7B%0A%20%20enabled%3A%20true%2C%0A%20%20requireEmailVerification%3A%20true%2C%0A%20%20onExistingUserSignUp%3A%20async%20%28%7B%20user%20%7D%2C%20request%29%20%3D%3E%20%7B%0A%20%20%20%20//%20Handle%20duplicate%20sign-up%20attempt%20here%0A%20%20%20%20console.log%28%60Duplicate%20sign-up%20attempt%20for%3A%20%24%7Buser.email%7D%60%29%3B%0A%20%20%7D%2C%0A%7D%0A%60%60%60%0A%0A%2A%2ATo%20restore%20the%20old%20error-throwing%20behavior%2A%2A%20%28not%20recommended%20for%20security%20reasons%29%2C%20set%20%60autoSignIn%3A%20true%60%20AND%20%60requireEmailVerification%3A%20false%60.%0A%0ARelated%20issue%3A%20%5B%238363%5D%28https%3A//github.com/better-auth/better-auth/issues/8363%29%20discusses%20this%20same%20behavior%20change.)&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/8480)
Author
Owner

@himself65 commented on GitHub (Mar 9, 2026):

See dosubot's comment

@himself65 commented on GitHub (Mar 9, 2026): See dosubot's comment
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#3016