{"record":{"id":"b89ee476a4591fec","repo":"bitwarden/server","slug":"invalid-license-key","errorCode":null,"errorMessage":"Invalid license key.","messagePattern":"Invalid license key\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Billing/Controllers/LicensesController.cs","lineNumber":58,"sourceCode":"        _userService = userService;\n        _organizationRepository = organizationRepository;\n        _getCloudOrganizationLicenseQuery = getCloudOrganizationLicenseQuery;\n        _validateBillingSyncKeyCommand = validateBillingSyncKeyCommand;\n        _currentContext = currentContext;\n    }\n\n    [HttpGet(\"user/{id}\")]\n    public async Task<UserLicense> GetUser(string id, [FromQuery] string key)\n    {\n        var user = await _userRepository.GetByIdAsync(new Guid(id));\n        if (user == null)\n        {\n            return null;\n        }\n        else if (!user.LicenseKey.Equals(key))\n        {\n            await Task.Delay(2000);\n            throw new BadRequestException(\"Invalid license key.\");\n        }\n\n        var license = await _userService.GenerateLicenseAsync(user, null);\n        return license;\n    }\n\n    /// <summary>\n    /// Used by self-hosted installations to get an updated license file\n    /// </summary>\n    [HttpGet(\"organization/{id}\")]\n    public async Task<OrganizationLicense> OrganizationSync(string id, [FromBody] SelfHostedOrganizationLicenseRequestModel model)\n    {\n        var organization = await _organizationRepository.GetByIdAsync(new Guid(id));\n        if (organization == null)\n        {\n            throw new NotFoundException(\"Organization not found.\");\n        }\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Billing/Controllers/LicensesController.cs#L40-L76","documentation":"Thrown (HTTP 400) by GET /licenses/user/{id}?key=... when the user exists but the supplied query key does not equal user.LicenseKey. A 2-second Task.Delay is applied before throwing to slow key enumeration. Note: a non-existent user returns null (HTTP 200 with null body), not this error.","triggerScenarios":"Wrong or stale license key in the ?key= query parameter; the license key was regenerated; caller knows a valid user id but not its current key.","commonSituations":"License key rotated in the cloud portal but the self-hosted retrieval config still holds the old key; transcription/copy error in the key.","solutions":["Retrieve the current license key from the user's billing settings in the cloud and use it as the ?key value.","Update any stored configuration referencing the old key.","Double-check there are no trailing spaces or encoding artifacts in the key."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the configured license key is non-empty and matches the expected format before calling.\nif (!licenseKey || licenseKey.length < EXPECTED_MIN_LEN) {\n  throw new Error('License key is missing or truncated');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const lic = await get(`/licenses/user/${id}?key=${encodeURIComponent(key)}`);\n} catch (e) {\n  if (e.isBadRequest && /invalid license key/i.test(e.message)) {\n    await refreshLicenseKeyFromCloud(); // fetch current key, then retry once\n  } else { throw e; }\n}","preventionTips":["Store the license key in version-controlled config and update it when re-issued.","Copy keys via clipboard to avoid transcription errors.","Regenerate the key in the cloud portal if its provenance is uncertain."],"tags":["billing","license","authentication","throttle","secret"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}