{"record":{"id":"9eb035ea4bf7a594","repo":"bitwarden/server","slug":"you-cannot-change-your-email-when-using-key-connec","errorCode":null,"errorMessage":"You cannot change your email when using Key Connector.","messagePattern":"You cannot change your email when using Key Connector\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"src/Api/Auth/Controllers/AccountsController.cs","lineNumber":134,"sourceCode":"        var user = await _userService.GetUserByPrincipalAsync(User);\n        if (user == null)\n        {\n            throw new UnauthorizedAccessException();\n        }\n\n        // TODO: PM-39120 - PM30806_SelfServiceChangeEmailCommand flag cleanup, remove the flag\n        // check and keep only the SelfServiceChangeEmailCommand call.\n        if (_featureService.IsEnabled(FeatureFlagKeys.PM30806_SelfServiceChangeEmailCommand))\n        {\n            await _selfServiceChangeEmailCommand.InitiateChangeEmailAsync(\n                user, model.MasterPasswordHash, model.NewEmail);\n\n            return;\n        }\n\n        if (user.UsesKeyConnector)\n        {\n            throw new BadRequestException(\"You cannot change your email when using Key Connector.\");\n        }\n\n        if (!await _userService.CheckPasswordAsync(user, model.MasterPasswordHash))\n        {\n            await Task.Delay(2000);\n            throw new BadRequestException(\"MasterPasswordHash\", \"Invalid password.\");\n        }\n\n        var claimedUserValidationResult = await _userService.ValidateClaimedUserDomainAsync(user, model.NewEmail);\n\n        if (!claimedUserValidationResult.Succeeded)\n        {\n            throw new BadRequestException(claimedUserValidationResult.Errors);\n        }\n\n        await _userService.InitiateEmailChangeAsync(user, model.NewEmail);\n    }\n","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Auth/Controllers/AccountsController.cs#L116-L152","documentation":"Thrown as a 400 BadRequestException(\"You cannot change your email when using Key Connector.\") from the legacy (feature-flag-off) path of POST accounts/email-token when user.UsesKeyConnector is true. Key Connector users obtain their user key from an external IdP/key source rather than from a master password, so the legacy local email-change flow (which rotates the master password and wrapped key) does not apply.","triggerScenarios":"A Key Connector-enabled user (SSO with Key Connector) calls POST accounts/email-token while the PM30806_SelfServiceChangeEmailCommand flag is OFF, hitting the legacy branch that rejects Key Connector accounts.","commonSituations":"SSO organization with Key Connector enabled; the client is on a build that still uses the legacy email-change endpoint; feature flag not yet rolled out to the deployment.","solutions":["Use the self-service change-email flow (the PM30806_SelfServiceChangeEmailCommand path) which supports Key Connector; ensure the feature flag is enabled.","If Key Connector must stay, change the email at the IdP and have the user re-provision rather than via this endpoint.","Update the client to a version that routes Key Connector users to the supported flow."],"exampleFix":"// before: legacy endpoint rejects Key Connector users\nawait api.post('accounts/email-token', { newEmail, masterPasswordHash });\n// after: use the self-service flow enabled by the feature flag\nawait api.post('accounts/email-token', { newEmail, masterPasswordHash }); // with flag PM30806 enabled server-side","handlingStrategy":"validation","validationCode":"function canChangeEmailLocally(user, flagOn) {\n  return !user.usesKeyConnector || flagOn;\n}","typeGuard":"function isKeyConnectorUser(u): boolean { return !!u && u.usesKeyConnector === true; }","tryCatchPattern":null,"preventionTips":["Gate the email-change UI on !usesKeyConnector or on the self-service feature flag.","Enable PM30806_SelfServiceChangeEmailCommand for Key Connector orgs.","For Key Connector users, change the email at the IdP and re-provision."],"tags":["bitwarden","key-connector","email-change","sso","feature-flag","aspnet"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}