{"record":{"id":"4f9d6bc1b04e0cbf","repo":"bitwarden/server","slug":"invalid-token","errorCode":null,"errorMessage":"Invalid token.","messagePattern":"Invalid token\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"bitwarden_license/src/Commercial.Core/AdminConsole/Services/ProviderService.cs","lineNumber":120,"sourceCode":"    }\n\n    public async Task<Provider> CompleteSetupAsync(Provider provider, Guid ownerUserId, string token, string key, TokenizedPaymentMethod paymentMethod, BillingAddress billingAddress)\n    {\n        var owner = await _userService.GetUserByIdAsync(ownerUserId);\n        if (owner == null)\n        {\n            throw new BadRequestException(\"Invalid owner.\");\n        }\n\n        if (provider.Status != ProviderStatusType.Pending)\n        {\n            throw new BadRequestException(\"Provider is already setup.\");\n        }\n\n        if (!CoreHelpers.TokenIsValid(\"ProviderSetupInvite\", _dataProtector, token, owner.Email, provider.Id,\n            _globalSettings.OrganizationInviteExpirationHours))\n        {\n            throw new BadRequestException(\"Invalid token.\");\n        }\n\n        var providerUser = await _providerUserRepository.GetByProviderUserAsync(provider.Id, ownerUserId);\n        if (!(providerUser is { Type: ProviderUserType.ProviderAdmin }))\n        {\n            throw new BadRequestException(\"Invalid owner.\");\n        }\n\n        var organizationAutoConfirmPolicyRequirement = await _policyRequirementQuery\n            .GetAsync<AutomaticUserConfirmationPolicyRequirement>(ownerUserId);\n\n        if (organizationAutoConfirmPolicyRequirement\n            .CannotCreateProvider())\n        {\n            throw new BadRequestException(new UserCannotJoinProvider().Message);\n        }\n\n        var customer = await _providerBillingService.SetupCustomer(provider, paymentMethod, billingAddress);","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/bitwarden_license/src/Commercial.Core/AdminConsole/Services/ProviderService.cs#L102-L138","documentation":"Thrown inside CompleteSetupAsync when the 'ProviderSetupInvite' data-protection token fails CoreHelpers.TokenIsValid (invalid or expired, governed by GlobalSettings.OrganizationInviteExpirationHours). The token binds the owner's email and the provider Id. BadRequestException (HTTP 400).","triggerScenarios":"Setup link used after the invite expiration window; tampered token; token generated for a different email or provider; data-protection key ring changed on the server.","commonSituations":"User delays setup beyond the invite window; server key rotation invalidating older tokens; owner email changed after the invite was generated.","solutions":["Regenerate the setup invite via SendProviderSetupInviteEmailAsync to mint a fresh token.","Confirm the token's embedded email still matches the owner's current email.","Check OrganizationInviteExpirationHours configuration if invites expire too aggressively."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!CoreHelpers.TokenIsValid(\"ProviderSetupInvite\", _dataProtector, token, owner.Email, provider.Id,\n        _globalSettings.OrganizationInviteExpirationHours))\n    throw new InvalidOperationException(\"Setup token is invalid or expired. Request a new invite.\");","typeGuard":null,"tryCatchPattern":"try { await _providerService.CompleteSetupAsync(provider, ownerUserId, token, key, payment, billing); }\ncatch (BadRequestException ex) when (ex.Message == \"Invalid token.\")\n{ /* regenerate invite via SendProviderSetupInviteEmailAsync */ }","preventionTips":["Regenerate setup invites when users report expired tokens.","Keep data-protection keys stable across deploys.","Set a reasonable OrganizationInviteExpirationHours."],"tags":["provider","setup","token","security","expiration","bitwarden"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}