bitwarden/server · error · BadRequestException

Organization already belongs to a provider.

Error message

Organization already belongs to a provider.

What it means

Thrown by ProviderService.AddOrganization when a ProviderOrganization already exists for the given organizationId (GetByOrganizationId returns non-null). An organization can only belong to one provider at a time. BadRequestException (HTTP 400).

Source

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

            catch (BadRequestException e)
            {
                result.Add(Tuple.Create(providerUser, e.Message));
            }

            await _providerUserRepository.DeleteManyAsync(deletedUserIds);
        }

        await _eventService.LogProviderUsersEventAsync(events);

        return result;
    }

    public async Task AddOrganization(Guid providerId, Guid organizationId, string key)
    {
        var po = await _providerOrganizationRepository.GetByOrganizationId(organizationId);
        if (po != null)
        {
            throw new BadRequestException("Organization already belongs to a provider.");
        }

        var organization = await _organizationRepository.GetByIdAsync(organizationId);

        var provider = await _providerRepository.GetByIdAsync(providerId);

        ThrowOnInvalidPlanType(provider.Type, organization.PlanType);

        if (organization.UseSecretsManager)
        {
            throw new BadRequestException(
                "The organization is subscribed to Secrets Manager. Please contact Customer Support to manage the subscription.");
        }

        var providerOrganization = new ProviderOrganization
        {
            ProviderId = providerId,
            OrganizationId = organizationId,

View on GitHub (pinned to e93b962371)

Solutions

  1. Before adding, call GetByOrganizationId(organizationId) and confirm it is null.
  2. If reassigning providers, remove the existing ProviderOrganization first, then add.
  3. Check the UI: if the org shows a current provider, route the user to transfer/flow rather than a plain add.

Example fix

// before
await providerService.AddOrganization(providerId, orgId, key);

// after
var existing = await _providerOrganizationRepository.GetByOrganizationId(orgId);
if (existing != null)
{
    throw new ConflictException($"Org already on provider {existing.ProviderId}.");
}
await providerService.AddOrganization(providerId, orgId, key);
Defensive patterns

Strategy: validation

Validate before calling

var existing = await providerOrganizationRepository.GetByOrganizationId(organizationId);
if (existing != null) throw new ConflictException("Already linked.");

Try / catch

try { await providerService.AddOrganization(providerId, orgId, key); }
catch (BadRequestException ex) when (ex.Message.Contains("already belongs")) { /* prompt transfer flow */ }

Prevention

When it happens

Trigger: Calling AddOrganization(providerId, organizationId, key) for an organization that is already linked to any provider (possibly the same or a different one).

Common situations: Re-adding an org that was moved but whose prior link wasn't cleared; an admin retrying a partially-completed add; an org already managed by a reseller being added to an MSP.

Related errors


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