bitwarden/server · error · BadRequestException

Email verified Sends require a premium membership

Error message

Email verified Sends require a premium membership

What it means

Thrown as BadRequestException (HTTP 400) from POST /sends (text/item creation) when the requesting user does not have premium access but the request body includes an Emails field (email-verified/OTP access). Email-verified Send access is a premium-only feature; the server rejects non-premium users attempting to use it.

Source

Thrown at src/Api/Tools/Controllers/SendsController.cs:240

                send.Id,
                EventType.Send_Accessed_File,
                orgContext);
        }

        return new ObjectResult(new SendFileDownloadDataResponseModel() { Id = fileId, Url = url });
    }

    [Authorize(Policies.Application)]
    [HttpPost("")]
    public async Task<SendResponseModel> Post([FromBody] SendRequestModel model)
    {
        model.ValidateCreation();
        var userId = _userService.GetProperUserId(User) ?? throw new InvalidOperationException("User ID not found");
        var hasPremium = await _hasPremiumAccessQuery.HasPremiumAccessAsync(userId);

        if (!hasPremium && !string.IsNullOrWhiteSpace(model.Emails))
        {
            throw new BadRequestException("Email verified Sends require a premium membership");
        }

        var send = model.ToSend(userId, _sendAuthorizationService);
        await _nonAnonymousSendCommand.SaveSendAsync(send);
        return new SendResponseModel(send);
    }

    [Authorize(Policies.Application)]
    [HttpPost("file/v2")]
    public async Task<SendFileUploadDataResponseModel> PostFile([FromBody] SendRequestModel model)
    {
        if (model.Type != SendType.File)
        {
            throw new BadRequestException("Invalid content.");
        }

        if (!model.FileLength.HasValue)
        {

View on GitHub (pinned to e93b962371)

Solutions

  1. Upgrade the user to an active premium subscription, or use password-auth/no-auth instead of email access.
  2. Clear the Emails field in the request when not using premium.
  3. Verify premium status via the billing/account endpoint before submitting.
  4. If org-sponsored premium, confirm the sponsorship is active and synced.

Example fix

// before
{ "type": 1, "emails": "a@b.com", ... } // free user -> 400

// after: omit emails or use password auth
{ "type": 1, "password": "...", ... }
Defensive patterns

Strategy: validation

Validate before calling

// Client: check premium before creating an email-verified Send
var hasPremium = await billingClient.HasPremiumAccessAsync();
if (!hasPremium && !string.IsNullOrWhiteSpace(model.Emails)) {
    ShowUser("Email-verified Sends require Bitwarden Premium.");
    return;
}
await client.PostAsync("sends", JsonContent.Create(model));

Prevention

When it happens

Trigger: POST /sends with a JSON body where model.Emails is non-empty AND the caller's HasPremiumAccessAsync returns false (free account, or premium not active/expired).

Common situations: Free-tier user selects 'email verification' access type in the client; premium subscription lapsed/expired but client still sends Emails; org-based premium not provisioned for the user; test account without premium.

Related errors


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