{"record":{"id":"e786f87d8c2a0aa7","repo":"bitwarden/server","slug":"user-not-found","errorCode":null,"errorMessage":"User not found.","messagePattern":"User not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"bitwarden_license/src/Scim/Controllers/v2/UsersController.cs","lineNumber":57,"sourceCode":"        IRestoreOrganizationUserCommand restoreOrganizationUserCommand,\n        IRevokeOrganizationUserCommandV2 revokeOrganizationUserCommandV2)\n    {\n        _organizationUserRepository = organizationUserRepository;\n        _getUsersListQuery = getUsersListQuery;\n        _removeOrganizationUserCommand = removeOrganizationUserCommand;\n        _patchUserCommand = patchUserCommand;\n        _postUserCommand = postUserCommand;\n        _restoreOrganizationUserCommand = restoreOrganizationUserCommand;\n        _revokeOrganizationUserCommandV2 = revokeOrganizationUserCommandV2;\n    }\n\n    [HttpGet(\"{id}\")]\n    public async Task<IActionResult> Get(Guid organizationId, Guid id)\n    {\n        var orgUser = await _organizationUserRepository.GetDetailsByIdAsync(id);\n        if (orgUser == null || orgUser.OrganizationId != organizationId)\n        {\n            throw new NotFoundException(\"User not found.\");\n        }\n        return Ok(new ScimUserResponseModel(orgUser));\n    }\n\n    [HttpGet(\"\")]\n    public async Task<IActionResult> Get(\n        Guid organizationId,\n        [FromQuery] GetUsersQueryParamModel model)\n    {\n        var usersListQueryResult = await _getUsersListQuery.GetUsersListAsync(organizationId, model);\n        var scimListResponseModel = new ScimListResponseModel<ScimUserResponseModel>\n        {\n            Resources = usersListQueryResult.userList.Select(u => new ScimUserResponseModel(u)).ToList(),\n            ItemsPerPage = model.Count,\n            TotalResults = usersListQueryResult.totalResults,\n            StartIndex = model.StartIndex,\n        };\n        return Ok(scimListResponseModel);","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/bitwarden_license/src/Scim/Controllers/v2/UsersController.cs#L39-L75","documentation":"Thrown as a NotFoundException (HTTP 404) by the SCIM v2 UsersController Get action when the organization user details for {id} cannot be found or the retrieved user's OrganizationId does not match the route's {organizationId}. The SCIM exception filter returns a SCIM-formatted 404. This enforces tenant isolation and informs the IdP that the user resource no longer exists.","triggerScenarios":"GET /v2/{organizationId}/Users/{id} where the organization user record was deleted, the user was revoked and purged, or the id belongs to a different organization. Occurs when an IdP queries for a user it cached but that has since been removed from Bitwarden.","commonSituations":"User was removed from the Bitwarden organization (or left the org) but the IdP still tracks them. Directory sync sent a GET for a user GUID that was never provisioned. Cross-tenant id confusion from misconfigured SCIM API keys.","solutions":["List users via GET /v2/{organizationId}/Users to find the correct GUID for the user.","If the user was removed, re-provision them via POST /v2/{organizationId}/Users.","Verify the organizationId matches the SCIM bearer token's organization scope.","Clear the IdP connector cache and re-sync to reconcile stale references."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before GETting a specific user, verify the id is known\nif (!await userExistsInIdpCache(userId))\n{\n    logger.Warn(\"User {UserId} not in local cache; skipping GET\", userId);\n    return null;\n}","typeGuard":null,"tryCatchPattern":"try { var user = await scimClient.GetUserAsync(orgId, userId); }\ncatch (ScimException ex) when (ex.StatusCode == 404)\n{ /* user removed — delete from IdP tracking or re-provision */ }","preventionTips":["Cache Bitwarden user GUIDs from list responses and purge entries that 404.","Run periodic full-sync to reconcile IdP state with Bitwarden.","Never retry a GET that 404s with the same id — it will not appear."],"tags":["scim","not-found","users","http-404","provisioning"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}