bitwarden/server · warning · UnauthorizedAccessException

Unauthorized.

Error message

Unauthorized.

What it means

Thrown by ProviderBillingService.GetAddableOrganizations when the requesting providerUser is not Confirmed (null or Status != Confirmed). Only confirmed provider members may list organizations that can be added to the provider. UnauthorizedAccessException (HTTP 401).

Source

Thrown at bitwarden_license/src/Commercial.Core/Billing/Providers/Services/ProviderBillingService.cs:332

        await csvWriter.WriteRecordsAsync(csvRows);

        await streamWriter.FlushAsync();

        memoryStream.Seek(0, SeekOrigin.Begin);

        return memoryStream.ToArray();
    }

    public async Task<IEnumerable<AddableOrganization>> GetAddableOrganizations(
        Provider provider,
        Guid userId)
    {
        var providerUser = await providerUserRepository.GetByProviderUserAsync(provider.Id, userId);

        if (providerUser is not { Status: ProviderUserStatusType.Confirmed })
        {
            throw new UnauthorizedAccessException();
        }

        var candidates = await organizationRepository.GetAddableToProviderByUserIdAsync(userId, provider.Type);

        var active = (await Task.WhenAll(candidates.Select(async organization =>
            {
                var subscription = await subscriberService.GetSubscription(organization);
                return (organization, subscription);
            })))
            .Where(pair => pair.subscription is
            {
                Status:
                SubscriptionStatus.Active or
                SubscriptionStatus.Trialing or
                SubscriptionStatus.PastDue
            }).ToList();

        if (active.Count == 0)

View on GitHub (pinned to e93b962371)

Solutions

  1. Require the user to accept and be confirmed on the provider before exposing the add-organizations action.
  2. Gate the UI on the provider membership status; hide the add flow until Confirmed.
  3. Return a clear 401/403 with a message rather than relying on the raw exception in API responses.

Example fix

// before
var orgs = await providerBillingService.GetAddableOrganizations(provider, userId);

// after
var pu = await providerUserRepository.GetByProviderUserAsync(provider.Id, userId);
if (pu is not { Status: ProviderUserStatusType.Confirmed })
    return Unauthorized("Confirm your provider membership first.");
var orgs = await providerBillingService.GetAddableOrganizations(provider, userId);
Defensive patterns

Strategy: validation

Validate before calling

var pu = await providerUserRepository.GetByProviderUserAsync(provider.Id, userId);
if (pu is not { Status: ProviderUserStatusType.Confirmed }) return Unauthorized("Not confirmed.");

Type guard

static bool IsConfirmedMember(ProviderUser? pu) => pu is { Status: ProviderUserStatusType.Confirmed };

Prevention

When it happens

Trigger: Calling GetAddableOrganizations with a userId whose ProviderUser for this provider is Invited, Accepted, or absent entirely.

Common situations: A newly invited provider admin who hasn't accepted/confirmed calling the add-org screen; a non-member attempting the call; session belonging to a user not linked to this provider.

Understand the failure class

Related errors


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