bitwarden/server · error · BadRequestException
Invalid Billing Sync Key
Error message
Invalid Billing Sync Key
What it means
Thrown (HTTP 400) by GET /licenses/organization/{id} when the license key matches but _validateBillingSyncKeyCommand.ValidateBillingSyncKeyAsync returns false. The billing sync key is the shared secret that pairs a self-hosted organization with its cloud billing subscription; a mismatch aborts license retrieval.
Source
Thrown at src/Api/Billing/Controllers/LicensesController.cs:85
/// </summary>
[HttpGet("organization/{id}")]
public async Task<OrganizationLicense> OrganizationSync(string id, [FromBody] SelfHostedOrganizationLicenseRequestModel model)
{
var organization = await _organizationRepository.GetByIdAsync(new Guid(id));
if (organization == null)
{
throw new NotFoundException("Organization not found.");
}
if (!organization.LicenseKey.Equals(model.LicenseKey))
{
await Task.Delay(2000);
throw new BadRequestException("Invalid license key.");
}
if (!await _validateBillingSyncKeyCommand.ValidateBillingSyncKeyAsync(organization, model.BillingSyncKey))
{
throw new BadRequestException("Invalid Billing Sync Key");
}
var license = await _getCloudOrganizationLicenseQuery.GetLicenseAsync(organization, _currentContext.InstallationId.Value);
return license;
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Regenerate the billing sync key in the cloud organization's billing settings and copy it exactly.
- Update the self-hosted billing-sync configuration with the new key.
- Verify the key was not truncated or altered during copy.
Defensive patterns
Strategy: validation
Validate before calling
// Verify the billing sync key is configured and well-formed before calling.
if (!billingSyncKey || billingSyncKey.length === 0) {
throw new Error('Billing sync key is not configured for this organization');
} Try / catch
try {
const lic = await getOrgLicense(orgId, body);
} catch (e) {
if (e.isBadRequest && /invalid billing sync key/i.test(e.message)) {
await regenerateAndStoreBillingSyncKey(); // then retry once
} else { throw e; }
} Prevention
- Store the billing sync key in a managed secret store, not inline code.
- Rotate keys deliberately and update all dependents atomically.
- Copy the key from the cloud portal via clipboard to avoid truncation.
When it happens
Trigger: Wrong or stale billing sync key; the key was regenerated in the cloud portal; the organization was never configured for billing sync.
Common situations: Billing sync key regenerated in cloud org settings but the self-hosted installation still uses the old key; fresh self-hosted install that was never paired.
Related errors
- Invalid license key.
- Invalid Billing Sync Key
- Organization not found.
- 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/e23ec890d28f4595.
Report an issue: GitHub.