bitwarden/server · error · BadRequestException

Premium status is required.

Error message

Premium status is required.

What it means

BadRequestException 'Premium status is required.' is thrown in ValidateUserHasPremiumAsync when _userService.CanAccessPremium(user) returns false. Certain two-factor providers (Duo) require a premium subscription (directly or via an org with premium); non-premium users are blocked before configuration is saved.

Source

Thrown at src/Api/Auth/Controllers/TwoFactorController.cs:563

        {
            throw new UnauthorizedAccessException();
        }

        if (!TwoFactorUserVerificationTokenable.Validate(
                _twoFactorUserVerificationDataProtector, userVerificationToken, user, providerType))
        {
            throw new BadRequestException("UserVerificationToken", "User verification failed.");
        }
        return user;
    }

    /// <summary>Verifies the user has premium access.</summary>
    /// <exception cref="BadRequestException">User cannot access premium.</exception>
    private async Task ValidateUserHasPremiumAsync(User user)
    {
        if (!await _userService.CanAccessPremium(user))
        {
            throw new BadRequestException("Premium status is required.");
        }
    }

    /// <summary>Mints a protected user-verification token bound to <paramref name="user"/> and <paramref name="providerType"/>.</summary>
    private string MintProtectedUserVerificationToken(User user, TwoFactorProviderType providerType)
    {
        var token = _twoFactorUserVerificationTokenableFactory.CreateToken(user, providerType);
        return _twoFactorUserVerificationDataProtector.Protect(token);
    }

    private async Task ValidateYubiKeyAsync(User user, string name, string value)
    {
        if (string.IsNullOrWhiteSpace(value) || value.Length == 12)
        {
            return;
        }

        if (!await _userManager.VerifyTwoFactorTokenAsync(user,

View on GitHub (pinned to e93b962371)

Solutions

  1. Upgrade the account to premium (or join a premium organization) before enabling Duo.
  2. On self-hosted, verify the installation license is installed and valid.
  3. Confirm the org membership still grants premium (seat not revoked).
  4. If premium was just purchased, allow time for propagation and re-check CanAccessPremium.

Example fix

// before
api.put('/users/two-factor/duo', { ... }) // free account
// after
await billingService.upgradeToPremium();
api.put('/users/two-factor/duo', { ... });
Defensive patterns

Strategy: validation

Validate before calling

const premium = await billingService.canAccessPremium();
if (!premium) throw new Error('Premium required for Duo two-factor');

Try / catch

try { await api.put('/users/two-factor/duo', model); }
catch (e) {
  if (e.response?.status === 400 && /Premium status is required/.test(e.response.data?.message)) {
    throw new UserFacingError('Upgrade to premium to enable Duo 2FA.');
  }
  throw e;
}

Prevention

When it happens

Trigger: PUT /api/users/two-factor/duo (PutDuo, and other premium-gated flows) called by a user with no active premium subscription and no premium-granting organization membership.

Common situations: Free-tier user attempting to enable Duo 2FA, an expired premium subscription, or a premium org whose membership/seat was removed. Self-hosted setups without a valid license also report non-premium.

Related errors


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