bitwarden/server · error · NotFoundException
Unable to get Cloud Billing Sync connection
Error message
Unable to get Cloud Billing Sync connection
What it means
Thrown as a NotFoundException (HTTP 404) by the cloud-billing-sync license-refresh path when the organization has no OrganizationConnection of type CloudBillingSync. The controller looks up connections of that type for the (validated) self-hosted org details and, finding none, treats the missing connection as a not-found resource rather than a permission error.
Source
Thrown at src/Api/Controllers/SelfHosted/SelfHostedOrganizationLicensesController.cs:121
public async Task SyncLicenseAsync(string id)
{
var selfHostedOrganizationDetails = await _organizationRepository.GetSelfHostedOrganizationDetailsById(new Guid(id));
if (selfHostedOrganizationDetails == null)
{
throw new NotFoundException();
}
if (!await _currentContext.OrganizationOwner(selfHostedOrganizationDetails.Id))
{
throw new NotFoundException();
}
var billingSyncConnection =
(await _organizationConnectionRepository.GetByOrganizationIdTypeAsync(selfHostedOrganizationDetails.Id,
OrganizationConnectionType.CloudBillingSync)).FirstOrDefault();
if (billingSyncConnection == null)
{
throw new NotFoundException("Unable to get Cloud Billing Sync connection");
}
var license =
await _getSelfHostedOrganizationLicenseQuery.GetLicenseAsync(selfHostedOrganizationDetails, billingSyncConnection);
var currentOrganization = await _organizationRepository.GetByLicenseKeyAsync(license.LicenseKey);
await _updateOrganizationLicenseCommand.UpdateLicenseAsync(selfHostedOrganizationDetails, license, currentOrganization);
var config = billingSyncConnection.GetConfig<BillingSyncConfig>();
config.LastLicenseSync = DateTime.Now;
billingSyncConnection.SetConfig(config);
await _organizationConnectionRepository.ReplaceAsync(billingSyncConnection);
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Create an OrganizationConnection of type CloudBillingSync for this organization in the web vault before refreshing.
- Confirm the connection is active and its BillingSyncConfig is populated (API key, etc.).
- Verify you are operating on the correct org id that owns the connection.
- Re-establish the connection if it was deleted and retry the refresh.
Example fix
// before: refresh with no CloudBillingSync connection -> 404
// await UpdateLicenseSyncAsync(orgId);
//
// after: ensure connection exists first
var conn = await GetCloudBillingSyncConnection(orgId);
if (conn == null) {
await CreateCloudBillingSyncConnection(orgId, billingSyncApiKey);
}
await UpdateLicenseSyncAsync(orgId); Defensive patterns
Strategy: validation
Validate before calling
// Ensure a CloudBillingSync connection exists before refreshing the license
const conns = await getOrgConnections(orgId, 'CloudBillingSync');
if (conns.length === 0) {
await createCloudBillingSyncConnection(orgId, billingSyncApiKey);
}
await refreshLicenseSync(orgId); Type guard
function hasCloudBillingSyncConnection(list) {
return Array.isArray(list) && list.some(c => c.type === 'CloudBillingSync' && c.enabled);
} Try / catch
try {
await refreshLicenseSync(orgId);
} catch (e) {
if (e.status === 404 && /billing sync connection/i.test(e.message)) {
await createCloudBillingSyncConnection(orgId, billingSyncApiKey);
await refreshLicenseSync(orgId); // one retry after setup
} else throw e;
} Prevention
- Create the CloudBillingSync organization connection (with a valid config) before triggering sync.
- Confirm the BillingSyncConfig is populated (API key, etc.).
- Operate on the org id that actually owns the connection.
When it happens
Trigger: Triggering a license sync/refresh for a self-hosted org that has not yet configured a Cloud Billing Sync organization connection, or whose connection was deleted. Caller is already verified as the org owner.
Common situations: Org admin sets up license sync but never created the CloudBillingSync connection in the web vault; connection was removed; wrong org selected; migration where the connection did not carry over.
Related errors
- Cannot create a {typedModel.Type} connection outside of a se
- Cannot verify license file.
- Resource not found.
- Cannot get a {type} connection outside of a self-hosted inst
- Invalid license
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/5484a8e5682a1f9d.
Report an issue: GitHub.