OrchardCMS/OrchardCore · error · ApplicationException
Couldn't generate a unique user id. Too many attempts.
Error message
Couldn't generate a unique user id. Too many attempts.
What it means
Thrown by UserStore.CreateAsync when the IUserIdGenerator fails to produce a unique UserId after 10 collision-check attempts against the UserIndex. Each attempt regenerates an id and re-queries the index; if all 10 collide, the store gives up rather than create a duplicate id. It indicates either a pathologically weak id generator or an index/query problem making every candidate appear taken.
Solutions
- Check the registered IUserIdGenerator implementation and ensure it emits high-entropy, unique ids (e.g. Guid-based).
- Verify the UserIndex index provider is correctly registered so the uniqueness query is accurate.
- Retry user creation once a collision burst has passed; if it persists, inspect the users table for duplicate/stale UserId values.
- Wrap CreateAsync in try-catch for ApplicationException and surface a user-friendly provisioning failure.
Example fix
// before services.AddSingleton<IUserIdGenerator, MyFixedPrefixGenerator>(); // after services.AddScoped<IUserIdGenerator, GuidUserIdGenerator>();
Defensive patterns
Strategy: try-catch
Validate before calling
var existing = await _session.QueryIndex<UserIndex>(x => x.UserId == candidateId).CountAsync();
if (existing != 0) { /* regenerate before calling CreateAsync */ } Type guard
bool IsUsableId(string id) => !string.IsNullOrWhiteSpace(id) && id.Length >= 16;
Try / catch
try { await _userManager.CreateAsync(user); }
catch (ApplicationException ex) when (ex.Message.Contains("unique user id"))
{ _logger.LogError(ex, "UserId generation exhausted retries"); return Problem("User provisioning failed"); } Prevention
- Use a Guid- or high-entropy-based IUserIdGenerator
- Keep the UserIndex provider correctly registered
- Load-test user provisioning with large user tables
- Never seed users with hand-crafted short ids
When it happens
Trigger: Creating a new user (CreateAsync) while a deterministic UserIdGenerator (e.g. one derived from the username/email) collides with existing users repeatedly; or the UserIndex query erroneously matches everything, so every candidate id appears taken.
Common situations: Custom or misconfigured IUserIdGenerator implementations that emit constant or low-entropy ids; large user tables with short/generated ids; broken UserIndex provider returning false positives during user provisioning or setup recipes.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Role does not exist.
- Provider is already linked for
- The name cannot be null or empty.
- The value cannot be null or empty.
- code cannot be null or empty.
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/9a48505ff694b945.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Users.Core/Services/UserStore.cs:95
}
var newUserId = newUser.UserId;
if (string.IsNullOrEmpty(newUserId))
{
// Due to database collation we normalize the userId to lower invariant.
newUserId = _userIdGenerator.GenerateUniqueId(user).ToLowerInvariant();
}
try
{
var attempts = 10;
while (await _session.QueryIndex<UserIndex>(x => x.UserId == newUserId).CountAsync(cancellationToken) != 0)
{
if (attempts-- == 0)
{
throw new ApplicationException("Couldn't generate a unique user id. Too many attempts.");
}
newUserId = _userIdGenerator.GenerateUniqueId(user).ToLowerInvariant();
}
newUser.UserId = newUserId;
var context = new UserCreateContext(user);
await Handlers.InvokeAsync((handler, context) => handler.CreatingAsync(context), context, _logger);
if (context.Cancel)
{
return IdentityResult.Failed();
}
await _session.SaveAsync(user, cancellationToken: cancellationToken);
await _session.FlushAsync(cancellationToken);View on GitHub (pinned to 4306c0717f)