# POST /api/v2/users Returns 409 Conflict ("User already exists") Despite No Existing Record – JIT Password Reset Flow Failing

**URL:** <https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267>\
**Category:** Get Help\
**Tags:** user-password-management, user-management\
**Created:** [December 7, 2025, 7:31pm UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267 "2025-12-07T19:31:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ray4](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ray4/32/73179_2.png) [@ray4](https://community.auth0.com/u/ray4)\
**Post date:** [December 7, 2025, 7:31pm UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267/1 "2025-12-07T19:31:03Z")

</div>

Hi Auth0 team, I’ve hit a critical blocker in my Just-In-Time (JIT) migration lab that I believe requires a backend review. I’ve included exhaustive logs and reproduction details below.\*\*

Tenant:\*\* `dev-cnhsg0roe6qny5na`  
**Region:** US  
**Environment:** Production-like lab setup (custom DB connection using Azure-based legacy backend APIs)  
**Impact:** Change Password → JIT user creation blocked, halting full migration flow

**Context**

I’m building a **Just-In-Time (JIT) migration** flow for Azure AD B2C migration into Auth0.  
The project has two core components:

1. **JIT Sign-In:** When a user logs in, Auth0 validates against my legacy API (`LocalAccountSignIn`) and creates the user dynamically in Auth0.

2. **JIT Forgot Password / Change Password:** When a currently non auth0 user triggers a password reset, Auth0 calls the same legacy API (`LocalAccountUserExists`), and if the user is not yet in Auth0, it attempts to create them using the Management API (`POST /api/v2/users`).

### **What Works**

- **JIT Sign-In:** Fully functional.  
-Auth0 successfully calls my legacy endpoint, validates credentials, and creates users on-the-fly.  
-Users appear correctly under the expected connection (`b2c-migrated-users-v2`).  
-All environment variables and secrets are correctly configured.

Example log excerpt: LOGIN SUCCESS [user\_id=ray.garg@zappsec.com](mailto:user_id=ray.garg@zappsec.com) migration\_status=completed

- The **login script** creates users _without_ going through `POST /api/v2/users`

- The **change password script** is the only place where `POST /api/v2/users` is called (for JIT creation during reset).

> In my current design:
> 
> - **JIT Sign-In** (Login script):  
> Uses the legacy `LocalAccountSignIn` API and returns a user profile directly to Auth0. This path does **not** use the Management API `POST /api/v2/users`. It works consistently.
> 
> - **JIT Forgot Password / Change Password** (Change Password script):  
> Uses `LocalAccountUserExists` and then calls `POST /api/v2/users` (Management API) **only when `users-by-email` returns empty**.  
> This is the path that fails with 409 `The user already exists.`

### **What Fails**

**Forgot Password / Change Password** flow fails **consistently** with:

POST /api/v2/users response status=409  
{  
“statusCode”: 409,  
“error”: “Conflict”,  
“message”: “The user already exists.”,  
“errorCode”: “auth0\_idp\_error”  
}

This occurs even when:

- `/api/v2/users-by-email` returns **empty** (`[]`)

- No users exist under this connection (`b2c-migrated-users-v2`)

- The user does **not** exist in any other connection

- I verified this using multiple advanced API searches (see below)

### **What I Have Already Tried**

#### **1. Fresh Connection Creation**

- Created an entirely new custom DB connection (`b2c-migrated-users-v2`)

- Copied verified scripts for `login`, `create`, `get user`, and `change password`

- Recreated **all environment variables** with identical key names

- Ensured `context` object was enabled in all scripts  
-JIT Sign-In on **b2c-migrated-users** and **b2c-migrated-users-v2** works reliably → confirms config + secrets + legacy APIs are correct.  
-Only the (Forgot Password) **Change Password → Management API create** branch fails with 409.

#### **2. Verified Application & M2M Toggles**

- Web App toggle → Enabled for `b2c-migrated-users-v2`

- M2M App toggle → Enabled for `b2c-migrated-users-v2`

- On the M2M app, Management API → Authorized with following scopes:

read:users  
update:users  
delete:users  
create:users  
update:users\_app\_metadata  
create:user\_tickets  
read:connections  
read:logs

#### **3. cURL Verification (Direct Management API)**

Generated M2M token:

```auto
curl --request POST \
  --url https://dev-cnhsg0roe6qny5na.us.auth0.com/oauth/token \
  --header 'content-type: application/json' \
  --data '{
    "client_id": "<client id here >",
    "client_secret": "<client secret here >",
    "audience": "https://<tenant>.us.auth0.com/api/v2/",
    "grant_type": "client_credentials"
  }'

```

Validated no duplicate users:

```auto
# Search by email
curl --request GET \
  --url "https://dev-cnhsg0roe6qny5na.us.auth0.com/api/v2/users?q=email%3A\"rgarg2%40ucsc.edu\"&search_engine=v3" \
  --header "authorization: Bearer <access_token>"
# → []

# Search by connection prefix
curl --request GET \
  --url "https://dev-cnhsg0roe6qny5na.us.auth0.com/api/v2/users?q=user_id%3A\"auth0%7Cb2c-migrated-users*\"&search_engine=v3" \
  --header "authorization: Bearer <access_token>"
# → []

```

Both queries confirm there are no visible users with this email or connection prefix.

**4. Confirmed Legacy API Responses**

`LocalAccountUserExists` returns expected JSON with `success=true` and valid legacy attributes.  
Response sample:

{  
“success”: true,  
“user”: {  
“user\_id”: “355f33ba-d08b-4170-9ca5-0f68cf43b7c8”,  
“email”: “rgarg2@ucsc.edu”,  
“email\_verified”: true,  
“name”: “Ray (UCSC JIT test) Garg”,  
“app\_metadata”: { “migration\_status”: “completed” }  
}  
}

5. Full Change Password Log Trace

CHANGE-PW DEBUG: user not in Auth0 → calling LEGACY\_EXIST  
CHANGE-PW LEGACY EXIST status=200 body={…}  
CHANGE-PW DEBUG: BRANCH=CREATE JIT localUserId=355f33ba-d08b…  
CHANGE-PW DEBUG: POST /api/v2/users connection=b2c-migrated-users-v2  
CHANGE-PW DEBUG: POST /users response status=409 body={“statusCode”:409,“error”:“Conflict”,“message”:“The user already exists.”,“errorCode”:“auth0\_idp\_error”}

### **Key Observation**

- `/users-by-email` consistently returns **zero** results.

- `/users` creation call **fails with 409 Conflict**.

- This occurs even on a **brand-new connection** , suggesting the duplication check may be **tenant-wide or cached** , possibly at the **normalized\_email index layer**.

### **What I Suspect (not confirmed)**

At first I suspected a stale identity index or tombstone for `rishug123@yahoo.com` left behind by a previously deleted user in another connection.  
However, this 409 behavior now occurs for **every email I test** in the JIT Forgot Password flow:

- `rgarg2@ucsc.edu`

- `rishug123@yahoo.com`

- `ray.garg@zappsec.com`

For each of these:

- `GET /api/v2/users-by-email` returns `[]`

- Search by `user_id` prefix for `auth0|b2c-migrated-users*` returns `[]`

That makes me wonder if there is:

- Some **tenant-wide uniqueness constraint** or

- Some **soft-deleted / cached entry** that is not visible via `/api/v2/users` but still blocks `POST /api/v2/users`.

### **Request for Engineering Assistance**

Please investigate at the **tenant-level identity store** for any residual or orphaned entries associated with:

- `email: rgarg2@ucsc.edu or rishug123@yahoo.com or ray.garg@zappsec.com. `I’m not certain this is the root cause, but given the behavior, I’d really appreciate a deeper backend check to rule this out.

- previous connection: `b2c-migrated-users`

- current connection: `b2c-migrated-users-v2`

If a stale entry exists in the internal store, please **purge or release it** so I can test creation again.

If not, I’d like confirmation of:

1. Whether Auth0 enforces tenant-wide uniqueness on `email` across multiple custom DB connections. Even if it does, i have made sure that the emails im testing with dont exist in the user directory before i try the jit forgot password flow.

2. Whether the `/users` endpoint may still reference cached soft-deleted entries.

3. Any recommended remediation beyond recreating connections (which I’ve already done).

### **Why This Matters**

This issue blocks our **JIT password-reset onboarding flow** , a key stage in our Auth0 adoption.  
Without resolution, no migrated user can complete their reset and activation process.  
The JIT login portion works flawlessly, so we know the code path and APIs are configured correctly, this is purely a user creation conflict preventing our production go-live.

**Expected Behavior**

If `/api/v2/users-by-email` returns `[]`, `POST /api/v2/users` should succeed in creating a new user under the specified connection.

### **Request Summary**

Please assist in:

- Verifying and clearing any orphaned identity index for `rgarg2@ucsc.edu/rishug123@yahoo.com/ray.garg@zappsec.com`

- Confirming whether Auth0 imposes a hidden tenant-wide uniqueness constraint between deleted records and new connection user creation

- Providing any mitigation or workaround that avoids the duplicate user creation error that comes from testing the jit forgot password flow

**Key questions for the Auth0 team**

1. Under what conditions can `POST /api/v2/users` return `409 The user already exists` when:

2. Are there **internal uniqueness constraints** (e.g. normalized email + connection) or **soft-deleted records** that are not visible via `/api/v2/users` but still block creation?

3. Is there any **tenant-level cache** or index that might need to be rebuilt or cleared by Auth0 engineering when many test users have been created/deleted across multiple custom DB connections?

4. Is there any recommended alternative pattern for:

**Thank you in advance.**  
I’ve spent several days reproducing this issue methodically across multiple connections and configurations, and I’m confident it’s not a misconfiguration or script-level bug. At this point I’ve exhausted what I can see from the configuration and scripts, and I’m leaning strongly toward this being an internal uniqueness/indexing issue rather than a script-level bug.  
At this point, I’m requesting a backend-level review of the tenant’s identity index and duplicate enforcement logic.

P.S If needed, I can securely share screenshots via DM or email.

---

<div class="post-metadata">

**Author:** ![nik.baleca](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/nik.baleca/32/68749_2.png) [@nik.baleca](https://community.auth0.com/u/nik.baleca)\
**Post date:** [December 9, 2025, 5:03pm UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267/3 "2025-12-09T17:03:40Z")

</div>

Hi again @ray4

In regards to the issue that you are experiencing, can you confirm that you **Create** script does not attempt to create the user in your Azure AD database as well besides creating the user in Auth0?

Usually, the **Create** script is used to create users in your current datastore whenever a user signs up through Auth0, not to create Auth0 users during a migration, that is what the Login script would be for.

You can try the following to remediate the issue that you are experiencing:

- Update your JIT Script. Modify the payload in your “Change Password” JIT script where you call the Management API. Add a specific flag in `user_metadata` to signal that this is a migration event.

```auto
const managementApiPayload = {
  connection: 'b2c-migrated-users-v2',
  email: email,
  password: tempPassword, 
  user_metadata: {
    is_jit_migration: true 
  }
};

```

- Update your Create script to check for this flag

```auto
function create(user, callback) {
  if (user.user_metadata && user.user_metadata.is_jit_migration) {

    console.log('JIT Migration detected: Skipping legacy DB creation for ' + user.email);

    return callback(null); 
  }

```

Let me know if this works for you, if not, I will be taking a look at your tenant configuration!

Kind Regards,  
Nik

---

<div class="post-metadata">

**Author:** ![ray4](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ray4/32/73179_2.png) [@ray4](https://community.auth0.com/u/ray4)\
**Post date:** [December 12, 2025, 12:08am UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267/4 "2025-12-12T00:08:24Z")

</div>

Hi @nik.baleca ,

Thank you again for your help. I implemented the `is_jit_migration` flag exactly as you suggested and updated both the Change Password script and the Create script accordingly.

Here is what I’m observing now:

### **1. `users-by-email` consistently returns zero results**

Example:

```auto
GETBYEMAIL: mgmt.getUsersByEmail status=200 body=[]

```

### **2. The Change Password script correctly hydrates the profile and attempts a JIT create**

```auto
BRANCH=CREATE JIT localUserId=d7f9... email=ray.garg@zappsec.com
profile={
  "connection":"b2c-migrated-users-v2",
  "email":"ray.garg@zappsec.com",
  "email_verified":true,
  "password":"Hello123!",
  "name":"Ray (Auth0Demo) Garg",
  "app_metadata":{"migration_status":"completed"},
  "user_metadata":{"is_jit_migration":true}
}

```

### **3. However, the Management API still returns 409 Conflict**

```auto
POST /api/v2/users → 409
body={"statusCode":409,"error":"Conflict","message":"The user already exists.","errorCode":"auth0_idp_error"}

```

### **4. This happens even on completely new emails**

I tested with:

- `ray.garg@zappsec.com`

- `rishug123@yahoo.com`

- rgarg2@ucsc.edu

All of them:

- Return `[]` from `/users-by-email`

- Then immediately fail with `409 – The user already exists`

### **Conclusion**

This appears to suggest the presence of an **orphaned or partially-created identity record** inside the `b2c-migrated-users-v2` connection that is not visible to `/users-by-email`.

Would you be able to inspect the tenant and the connection backend to confirm if these identities exist in the internal connection store?

Happy to provide any other logs you need, thank you again for taking the time to help me resolve this.

Best regards,  
Ray

---

<div class="post-metadata">

**Author:** ![ray4](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ray4/32/73179_2.png) [@ray4](https://community.auth0.com/u/ray4)\
**Post date:** [December 20, 2025, 10:42pm UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267/5 "2025-12-20T22:42:17Z")

</div>

Hi @nik.baleca quick follow-up with fresh update + logs.

**Status:** The JIT forgot-password flow is still failing for me due to an inconsistency between Management API “lookup” and “create”.

Current behavior troubleshooting (still 100% consistent)

1. From my app, I trigger **Forgot Password** for `<test email>` and Auth0 sends the reset email.

2. I click the reset link, submit new password on Auth0 hosted reset page.

3. My Custom DB `changePassword` runs and attempts JIT-create via Management API.

### What I’m seeing in logs

- `GETBYEMAIL` runs and shows `mgmt.getUsersByEmail count=0`, then my upstream legacy EXIST API confirms the user exists.

- In `changePassword`, **context flags are not present** in this flow in my tenant:

- Mgmt API lookup returns empty:

- But create conflicts:

- I added a belt-and-suspenders retry (re-query users-by-email multiple times after 409), but it stays `[]`, so the fallback cannot proceed.

So from the tenant’s perspective: **the user “exists” enough to block creation, but is not returned by users-by-email**.

### Parallel progress (not blocked)

- Bulk migration sign-in is working (users land with `migration_status=pending`, then complete on first login).

- I’m currently hardening **bulk-migrated forgot password** (patch existing Auth0 user + update B2C password during the transition window + service bus move to native Auth0 DB).

### Plan B for JIT forgot-password (fallback):

If this tenant-level inconsistency can’t be resolved quickly, I’m planning to handle JIT forgot-password via a fully custom reset email + reset UI that updates the password in B2C only; then the user’s next Auth0 login succeeds via ROPC and the existing login-script JIT creation path. Let me know anything to look out for as I approach this, that would be much appreciated.

**Question:** Is there a known scenario where `/api/v2/users-by-email` returns `[]` while `/api/v2/users` returns 409 for the same email/connection (ghost/soft-deleted user, indexing/caching issue, blocked state, etc.)? If so, what’s the recommended remediation to clear that state?

---

<div class="post-metadata">

**Author:** ![nik.baleca](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/nik.baleca/32/68749_2.png) [@nik.baleca](https://community.auth0.com/u/nik.baleca)\
**Post date:** [January 5, 2026, 4:51pm UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267/6 "2026-01-05T16:51:25Z")

</div>

Hi again @ray4

I am sorry about the delayed response to your update and extra information about the matter.

You are asking why `POST /api/v2/users` returns `409 The user already exists` during the Change Password flow for users who are still only in your legacy system, even though `users-by-email` returns no results.

[Root Cause]

### **1. Misconfigured “Get User” Script**

The “Get User” script for your Custom Database is executed prior to user creation. If this script is misconfigured and returns a profile for a non-existent user instead of a `null` value, Auth0 will interpret this as the user already existing and will block the creation process.

### **2. Pending Password Reset Record**

A conflict can occur if a user completed a password reset but has not yet signed in. This is common when a Custom Database has **Import Mode** enabled. In this case, Auth0 stores the new password in a temporary record that may not appear in standard Dashboard searches but still creates a conflict for new user creation.

**[Solution]** The 409 is most likely caused by a temporary profile that Auth0 creates when an un-migrated user completes a password reset. That profile is not returned by standard user searches, but it still blocks creation of a new user with the same email. A second possible cause is a Get User script that returns an object instead of `null` for users that do not exist in the legacy system. Auth0 cannot purge tenant-level records through the community, so the remaining records must be verified through official Support.

1. **Verify** the Get User script returns `null` for a missing user. Open **Connections → Database → [your custom database] → Custom Database**, select the **Get User** script, and run it in the **Test** section with an email that does not exist in your legacy system. The output must be `null`, not `{}` or a profile object.
2. **Search** for the temporary record by calling `GET /api/v2/users?q=email:"<address>"` with the email in question, and **filter** by the custom database connection name in the Dashboard Users page. Note that a temporary record may not appear in standard searches.
3. **Review** your Change Password script so that it does not call `POST /api/v2/users` for users who have not yet been imported. For un-migrated users, let the custom database import process create the user at first sign-in, and confirm the behavior with Support before go-live.
4. **Retest** the JIT password reset flow with a new email address that has never been used in this tenant, and confirm the user appears under the expected connection after the first sign-in.

Kind Regards,  
Nik

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/auth0/original/3X/b/5/b560f266932fcce5d57f09a6595bd50518cae3f3.jpeg) [@system](https://community.auth0.com/u/system)\
**Post date:** [January 19, 2026, 4:52pm UTC](https://community.auth0.com/t/post-api-v2-users-returns-409-conflict-user-already-exists-despite-no-existing-record-jit-password-reset-flow-failing/195267/7 "2026-01-19T16:52:15Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
