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
- Upgrade the user to an active premium subscription, or use password-auth/no-auth instead of email access.
- Clear the Emails field in the request when not using premium.
- Verify premium status via the billing/account endpoint before submitting.
- 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
- Disable the email-access option in the client UI for non-premium users.
- Refresh premium status after subscription changes.
- Default non-premium users to password or no-auth Send access.
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
- Could not locate send
- Invalid content.
- Invalid content. File size hint is required.
- Max file size is {SendFileSettingHelper.MAX_FILE_SIZE_READAB
- File metadata is required for file sends.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/0d1728a7eff249fb.
Report an issue: GitHub.