bitwarden/server · error · BadRequestException

Org admin not found.

Error message

Org admin not found.

What it means

Thrown by ProviderService.InitiateDeleteAsync when the user found by email is not a Confirmed ProviderAdmin of the provider being deleted (providerAdminOrgUser is null, or Status != Confirmed, or Type != ProviderAdmin). Only a confirmed admin of that provider may authorize its deletion. BadRequestException (HTTP 400).

Source

Thrown at bitwarden_license/src/Commercial.Core/AdminConsole/Services/ProviderService.cs:696

    }

    public async Task InitiateDeleteAsync(Provider provider, string providerAdminEmail)
    {
        if (string.IsNullOrWhiteSpace(provider.Name))
        {
            throw new BadRequestException("Provider name not found.");
        }
        var providerAdmin = await _userRepository.GetByEmailAsync(providerAdminEmail);
        if (providerAdmin == null)
        {
            throw new BadRequestException("Provider admin not found.");
        }

        var providerAdminOrgUser = await _providerUserRepository.GetByProviderUserAsync(provider.Id, providerAdmin.Id);
        if (providerAdminOrgUser == null || providerAdminOrgUser.Status != ProviderUserStatusType.Confirmed ||
            providerAdminOrgUser.Type != ProviderUserType.ProviderAdmin)
        {
            throw new BadRequestException("Org admin not found.");
        }

        var token = _providerDeleteTokenDataFactory.Protect(new ProviderDeleteTokenable(provider, 1));
        await _mailService.SendInitiateDeletProviderEmailAsync(providerAdminEmail, provider, token);
    }

    public async Task DeleteAsync(Provider provider, string token)
    {
        if (!_providerDeleteTokenDataFactory.TryUnprotect(token, out var data) || !data.Valid || !data.IsValid(provider))
        {
            throw new BadRequestException("Invalid token.");
        }
        await DeleteAsync(provider);
    }

    public async Task DeleteAsync(Provider provider)
    {
        await _providerRepository.DeleteAsync(provider);

View on GitHub (pinned to e93b962371)

Solutions

  1. Use the email of a confirmed ProviderAdmin of the specific provider being deleted.
  2. Confirm/accept the admin's provider invitation first, then initiate deletion.
  3. Verify providerAdminOrgUser.Type == ProviderAdmin and Status == Confirmed before calling.

Example fix

// before
await providerService.InitiateDeleteAsync(provider, adminEmail);

// after
var admin = await _userRepository.GetByEmailAsync(adminEmail);
var pu = await _providerUserRepository.GetByProviderUserAsync(provider.Id, admin.Id);
if (pu is not { Type: ProviderUserType.ProviderAdmin, Status: ProviderUserStatusType.Confirmed })
{
    return BadRequest("Admin is not a confirmed provider admin.");
}
await providerService.InitiateDeleteAsync(provider, adminEmail);
Defensive patterns

Strategy: validation

Validate before calling

var pu = await providerUserRepository.GetByProviderUserAsync(provider.Id, admin.Id);
if (pu is not { Type: ProviderUserType.ProviderAdmin, Status: ProviderUserStatusType.Confirmed })
    return BadRequest("Not a confirmed provider admin.");

Type guard

static bool IsConfirmedAdmin(ProviderUser? pu) =>
    pu is { Type: ProviderUserType.ProviderAdmin, Status: ProviderUserStatusType.Confirmed };

Prevention

When it happens

Trigger: Initiating deletion with an email whose user exists but is not linked to this provider, is still Invited/Accepted (not Confirmed), or is a ServiceUser/ProviderUser but not ProviderAdmin.

Common situations: Using a billing-only or lower-privilege contact email; an admin whose invitation was never accepted/confirmed; a user who belongs to a different provider.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/86a1dffb716aaa60. Report an issue: GitHub.