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

  1. Check the registered IUserIdGenerator implementation and ensure it emits high-entropy, unique ids (e.g. Guid-based).
  2. Verify the UserIndex index provider is correctly registered so the uniqueness query is accurate.
  3. Retry user creation once a collision burst has passed; if it persists, inspect the users table for duplicate/stale UserId values.
  4. 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

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


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)