{"record":{"id":"cc6565a4e234fe72","repo":"bitwarden/server","slug":"cannot-autoscale-on-a-self-hosted-instance-cc6565","errorCode":null,"errorMessage":"Cannot autoscale on a self-hosted instance.","messagePattern":"Cannot autoscale on a self-hosted instance\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/SecretsManager/Controllers/ServiceAccountsController.cs","lineNumber":143,"sourceCode":"        [FromBody] ServiceAccountCreateRequestModel createRequest)\n    {\n        var serviceAccount = createRequest.ToServiceAccount(organizationId);\n        var authorizationResult =\n            await _authorizationService.AuthorizeAsync(User, serviceAccount, ServiceAccountOperations.Create);\n\n        if (!authorizationResult.Succeeded)\n        {\n            throw new NotFoundException();\n        }\n\n        var newServiceAccountSlotsRequired = await _countNewServiceAccountSlotsRequiredQuery\n            .CountNewServiceAccountSlotsRequiredAsync(organizationId, 1);\n        if (newServiceAccountSlotsRequired > 0)\n        {\n            // Self-hosted instances can't autoscale their Stripe subscription, so reject before touching billing.\n            if (_globalSettings.SelfHosted)\n            {\n                throw new BadRequestException(\"Cannot autoscale on a self-hosted instance.\");\n            }\n\n            var org = await _organizationRepository.GetByIdAsync(organizationId);\n            var plan = await _pricingClient.GetPlanOrThrow(org!.PlanType);\n            var update = new SecretsManagerSubscriptionUpdate(org, plan, true)\n                .AdjustServiceAccounts(newServiceAccountSlotsRequired);\n            await _updateSecretsManagerSubscriptionCommand.UpdateSubscriptionAsync(update);\n        }\n\n        var userId = _userService.GetProperUserId(User).Value;\n\n        var result =\n            await _createServiceAccountCommand.CreateAsync(serviceAccount, userId);\n\n        if (result != null)\n        {\n            await _eventService.LogServiceAccountEventAsync(userId, [serviceAccount], EventType.ServiceAccount_Created, _currentContext.IdentityClientType);\n        }","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/SecretsManager/Controllers/ServiceAccountsController.cs#L125-L161","documentation":"Thrown by CreateAsync when the organization is self-hosted AND creating this service account would require additional service-account slots (autoscaling). Self-hosted instances cannot automatically adjust a Stripe subscription, so the server rejects the creation with a 400 BadRequest before touching billing. The guard fires only when newServiceAccountSlotsRequired > 0 on a self-hosted deployment.","triggerScenarios":"POST /organizations/{organizationId}/service-accounts on a self-hosted Bitwarden instance where the org has exhausted its allocated service-account slots and the new account would exceed the limit.","commonSituations":"Self-hosted deployment with a fixed SM subscription; org has used all purchased service-account seats and the admin tries to add more via API without first upgrading the license.","solutions":["Increase the service-account slot count in the self-hosted license/subscription before creating new service accounts.","Delete an unused service account to free a slot, then retry the creation.","Contact Bitwarden to update the self-hosted license with additional service-account seats."],"exampleFix":"// before: at slot limit on self-hosted\nPOST /organizations/{orgId}/service-accounts  // -> 400\n// after: free a slot or update license, then retry\nDELETE /service-accounts/{unusedId}\nPOST /organizations/{orgId}/service-accounts  // -> 200","handlingStrategy":"validation","validationCode":"// On self-hosted: check available slots before creating\nvar slotsNeeded = await countSlotsQuery.CountNewServiceAccountSlotsRequiredAsync(orgId, 1);\nif (globalSettings.SelfHosted && slotsNeeded > 0)\n{\n    return BadRequest(\"Free a slot or upgrade the license before creating a service account.\");\n}\nawait serviceAccountsClient.CreateAsync(organizationId, request);","typeGuard":null,"tryCatchPattern":"try { await client.CreateAsync(orgId, req); }\ncatch (ApiException ex) when (ex.Message.Contains(\"autoscale\")) { /* upgrade license */ }","preventionTips":["Monitor service-account slot usage on self-hosted deployments.","Delete unused service accounts before creating new ones at the limit.","Keep the self-hosted license updated with sufficient seats."],"tags":["secrets-manager","self-hosted","billing","service-accounts","bitwarden"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}