bitwarden/server · error · NotFoundException

Resource not found.

Error message

Resource not found.

What it means

Thrown as NotFoundException (HTTP 404) from DELETE /accounts/sso/{organizationId}. _userService.GetProperUserId(User) returns null because the authenticated ClaimsPrincipal does not carry a recognizable user ID claim. The controller throws new NotFoundException() which the ExceptionHandlerFilterAttribute maps to HTTP 404 with the generic message 'Resource not found.'

Source

Thrown at src/Api/Auth/Controllers/AccountsController.cs:652

            return;
        }

        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }

        await Task.Delay(2000);
        throw new BadRequestException(ModelState);
    }

    [HttpDelete("sso/{organizationId}")]
    public async Task DeleteSsoUser(string organizationId)
    {
        var userId = _userService.GetProperUserId(User);
        if (!userId.HasValue)
        {
            throw new NotFoundException();
        }

        await _organizationService.DeleteSsoUserAsync(userId.Value, new Guid(organizationId));
    }

    [HttpGet("sso/user-identifier")]
    public async Task<string> GetSsoUserIdentifier()
    {
        var user = await _userService.GetUserByPrincipalAsync(User);
        var token = await _userService.GenerateSignInTokenAsync(user, TokenPurposes.LinkSso);
        var userIdentifier = $"{user.Id},{token}";
        return userIdentifier;
    }

    [HttpPost("api-key")]
    public async Task<ApiKeyResponseModel> ApiKey([FromBody] SecretVerificationRequestModel model)
    {
        var user = await _userService.GetUserByPrincipalAsync(User);

View on GitHub (pinned to e93b962371)

Solutions

  1. Inspect the JWT claims (specifically the 'sub' or nameidentifier claim) to confirm a valid Bitwarden user Guid is present.
  2. Re-authenticate the user to obtain a fresh access token with complete claims.
  3. If using SSO, verify the SSO provider's claim mapping includes the user identifier.
  4. Check that the authentication middleware (JwtBearer or cookie) is correctly registered and executed before the controller.

Example fix

// before: calling with a token missing user ID claims
client.DefaultRequestHeaders.Authorization = new("Bearer", staleOrIncompleteToken);
await client.DeleteAsync($"/accounts/sso/{orgId}"); // 404

// after: re-authenticate to get a complete token
var token = await authService.GetAccessTokenAsync(username, password);
client.DefaultRequestHeaders.Authorization = new("Bearer", token);
await client.DeleteAsync($"/accounts/sso/{orgId}");
Defensive patterns

Strategy: validation

Validate before calling

// Validate that the token contains a user ID claim before making the call
var handler = new JwtSecurityTokenHandler();
var jwt = handler.ReadJwtToken(accessToken);
var hasUserId = jwt.Claims.Any(c => c.Type == "sub" || c.Type == ClaimTypes.NameIdentifier);
if (!hasUserId) {
    // Re-authenticate before proceeding
    accessToken = await ReauthenticateAsync();
}

Try / catch

try {
    await client.DeleteAsync($"/accounts/sso/{organizationId}");
} catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound) {
    // Most likely the token lacks user ID claims — re-authenticate
    await ReauthenticateAsync();
    logger.LogWarning("SSO user deletion returned 404; token may lack user claims");
}

Prevention

When it happens

Trigger: An authenticated request to DELETE /accounts/sso/{organizationId} arrives with a bearer token whose claims are missing or malformed — GetProperUserId cannot extract a Guid user ID from the principal's claims.

Common situations: The access token expired and was silently renewed with a token that lacks the sub/nameidentifier claim. A misconfigured SSO provider omits the user identifier claim. The token was minted for a service account or machine-to-machine flow that does not include a Bitwarden user ID. The middleware pipeline is misconfigured and the principal is not populated.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/9364f965dd62bf53. Report an issue: GitHub.