bitwarden/server · error · Exception
No license to generate.
Error message
No license to generate.
What it means
Thrown in the GenerateLicense action when neither a valid user nor a valid organization was resolved from the submitted model. The code checks model.UserId and model.OrganizationId, loads the respective entity, and if both are null/unset (and ModelState is otherwise valid), this else-branch fires. It indicates the form was submitted with neither a user ID nor an organization ID.
Source
Thrown at src/Admin/Controllers/ToolsController.cs:337
var license = await _getCloudOrganizationLicenseQuery.GetLicenseAsync(organization,
model.InstallationId.Value, model.Version);
var ms = new MemoryStream();
await JsonSerializer.SerializeAsync(ms, license, JsonHelpers.Indented);
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "text/plain", "bitwarden_organization_license.json");
}
else if (user != null)
{
var license = await _userService.GenerateLicenseAsync(user, null, model.Version);
var ms = new MemoryStream();
ms.Seek(0, SeekOrigin.Begin);
await JsonSerializer.SerializeAsync(ms, license, JsonHelpers.Indented);
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "text/plain", "bitwarden_premium_license.json");
}
else
{
throw new Exception("No license to generate.");
}
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Ensure the license generation form has either a UserId or an OrganizationId filled before submission.
- Add server-side ModelState validation that at least one of UserId/OrganizationId is required (it appears ModelState may pass when both are null since they are optional fields).
- If calling the endpoint programmatically, always include one of the two IDs in the request body.
- Consider adding a [Required] attribute on a custom validation property to enforce mutual exclusivity and presence.
Example fix
// before: no validation for at-least-one
// after: add a model-level validation
if (!model.UserId.HasValue && !model.OrganizationId.HasValue)
{
ModelState.AddModelError(string.Empty, "Either User Id or Organization Id is required.");
return View(model);
} Defensive patterns
Strategy: validation
Validate before calling
// Server-side: enforce at least one target before processing
if (!model.UserId.HasValue && !model.OrganizationId.HasValue)
{
ModelState.AddModelError(string.Empty, "Either User Id or Organization Id is required.");
return View(model);
} Type guard
static bool HasLicenseTarget(LicenseModel model)
=> model.UserId.HasValue || model.OrganizationId.HasValue; Prevention
- Add a custom validation attribute (IValidatableObject) on LicenseModel to enforce mutual presence.
- Disable the submit button client-side until either a user or org is selected.
- Add an integration test that posts a model with neither ID and asserts a validation error (not a 500).
When it happens
Trigger: An admin submits the license generation form without selecting either a user or an organization. This is typically unreachable in the normal UI flow because form validation should catch the empty state, but can be triggered by a direct API call or a client-side validation bypass.
Common situations: A direct HTTP POST to the GenerateLicense endpoint with an empty body or a body missing both UserId and OrganizationId. A browser extension or script that bypasses client-side validation. A UI bug that allows submission without selecting a target.
Related errors
- Invalid license
- The specified sponsored organization could not be found unde
- Invalid owner. Owner must be an existing Bitwarden user.
- Failed to remove organization vault. Please contact support.
- Organization must have at least one confirmed owner.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/2052f4a4a376ad2c.
Report an issue: GitHub.