bitwarden/server · error · Exception
InvalidUserIdentifier
Error message
InvalidUserIdentifier
What it means
Thrown during SSO login when the manual user-linking identifier string does not contain at least two comma-separated segments. The identifier is expected in the format 'userId,token' and is split on ','; if fewer than two parts result, the format is considered invalid. This path is reached only when a userIdentifier value is present in the SSO callback (manual linking flow) at AccountController.cs:549.
Source
Thrown at bitwarden_license/src/Sso/Controllers/AccountController.cs:789
OrganizationUserStatusType.Invited,
OrganizationUserStatusType.Accepted,
OrganizationUserStatusType.Confirmed,
],
organization.DisplayName());
}
else
{
throw new Exception(_i18nService.T("CouldNotFindOrganizationUser", user.Id, organization.Id));
}
}
private async Task<User?> GetUserFromManualLinkingDataAsync(string userIdentifier)
{
User? user = null;
var split = userIdentifier.Split(",");
if (split.Length < 2)
{
throw new Exception(_i18nService.T("InvalidUserIdentifier"));
}
var userId = split[0];
var token = split[1];
var tokenOptions = new TokenOptions();
var claimedUser = await _userService.GetUserByIdAsync(userId);
if (claimedUser != null)
{
var tokenIsValid = await _userManager.VerifyUserTokenAsync(
claimedUser, tokenOptions.PasswordResetTokenProvider, TokenPurposes.LinkSso, token);
if (tokenIsValid)
{
user = claimedUser;
}
else
{View on GitHub (pinned to e93b962371)
Solutions
- Ensure the userIdentifier passed to the SSO flow is always formatted as 'userId,token' with both segments non-empty.
- Audit the client or middleware that builds the manual linking data to confirm it appends the LinkSso token after the comma.
- If the token is missing, regenerate the SSO linking invitation from the organization admin console so a fresh token is issued.
Example fix
// before
var userIdentifier = userId.ToString();
// after
var token = await userManager.GenerateUserTokenAsync(user, tokenOptions.PasswordResetTokenProvider, TokenPurposes.LinkSso);
var userIdentifier = $"{user.Id},{token}"; Defensive patterns
Strategy: validation
Validate before calling
// Validate userIdentifier format before calling the SSO linking API
if (string.IsNullOrWhiteSpace(userIdentifier) ||
userIdentifier.Split(',').Length < 2 ||
string.IsNullOrWhiteSpace(userIdentifier.Split(',')[0]) ||
string.IsNullOrWhiteSpace(userIdentifier.Split(',')[1]))
{
return BadRequest("userIdentifier must be in 'userId,token' format with both parts non-empty.");
} Type guard
// C# has no runtime type guard for strings; use a validation method
static bool IsValidUserIdentifier(string identifier)
=> !string.IsNullOrWhiteSpace(identifier)
&& identifier.Split(',').Length >= 2
&& identifier.Split(',').All(p => !string.IsNullOrWhiteSpace(p)); Try / catch
try { var user = await GetUserFromManualLinkingDataAsync(userIdentifier); }
catch (Exception ex) when (ex.Message.Contains("InvalidUserIdentifier"))
{ /* Show user-friendly 'linking data is malformed' message, prompt re-invitation */ } Prevention
- Always construct the userIdentifier as $"{userId},{token}" with both values validated non-empty.
- Add a unit test that asserts GetUserFromManualLinkingDataAsync rejects malformed identifiers.
- Log the userIdentifier length (not value) when this fires to diagnose truncation.
When it happens
Trigger: An SSO authentication callback carries a userIdentifier that is empty, has no comma, or is a single token. This happens when the linking URL/state is truncated, manually edited, or generated by a client that omits the token portion.
Common situations: A custom or older client constructs the linking payload without the LinkSso token. The user copies/pastes a partial linking URL. A bug in the calling code serializes only the userId without the comma-delimited token.
Related errors
- SSOProviderIsNotAnOrgId
- UserIdAndTokenMismatch
- CouldNotFindOrganization
- OrganizationUserAccessRevoked
- OrganizationUserUnknownStatus
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/9e825b61a4230533.
Report an issue: GitHub.