bitwarden/server · error · NotFoundException
Resource not found.
Error message
Resource not found.
What it means
Thrown by ListByOrganizationAsync (GET /organizations/{organizationId}/service-accounts) when _currentContext.AccessSecretsManager(organizationId) returns false. The 404 intentionally hides the existence of service accounts from callers without SM access for the org.
Source
Thrown at src/Api/SecretsManager/Controllers/ServiceAccountsController.cs:93
_serviceAccountSecretsDetailsQuery = serviceAccountSecretsDetailsQuery;
_createServiceAccountCommand = createServiceAccountCommand;
_updateServiceAccountCommand = updateServiceAccountCommand;
_deleteServiceAccountsCommand = deleteServiceAccountsCommand;
_revokeAccessTokensCommand = revokeAccessTokensCommand;
_pricingClient = pricingClient;
_createAccessTokenCommand = createAccessTokenCommand;
_updateSecretsManagerSubscriptionCommand = updateSecretsManagerSubscriptionCommand;
_eventService = eventService;
_globalSettings = globalSettings;
}
[HttpGet("/organizations/{organizationId}/service-accounts")]
public async Task<ListResponseModel<ServiceAccountSecretsDetailsResponseModel>> ListByOrganizationAsync(
[FromRoute] Guid organizationId, [FromQuery] bool includeAccessToSecrets = false)
{
if (!_currentContext.AccessSecretsManager(organizationId))
{
throw new NotFoundException();
}
var userId = _userService.GetProperUserId(User).Value;
var orgAdmin = await _currentContext.OrganizationAdmin(organizationId);
var accessClient = AccessClientHelper.ToAccessClient(_currentContext.IdentityClientType, orgAdmin);
var results =
await _serviceAccountSecretsDetailsQuery.GetManyByOrganizationIdAsync(organizationId, userId, accessClient,
includeAccessToSecrets);
var responses = results.Select(r => new ServiceAccountSecretsDetailsResponseModel(r));
return new ListResponseModel<ServiceAccountSecretsDetailsResponseModel>(responses);
}
[HttpGet("{id}")]
public async Task<ServiceAccountResponseModel> GetByServiceAccountIdAsync(
[FromRoute] Guid id)
{
var serviceAccount = await _serviceAccountRepository.GetByIdAsync(id);View on GitHub (pinned to e93b962371)
Solutions
- Confirm Secrets Manager is enabled on the target organization.
- Ensure the authenticated user or service account has SM access for that orgId.
- Regenerate or refresh the access token after SM access was granted.
Defensive patterns
Strategy: validation
Validate before calling
// Verify SM access before listing service accounts
if (!currentContext.AccessSecretsManager(organizationId))
{
return Forbid();
}
var result = await serviceAccountsClient.ListByOrganizationAsync(organizationId); Prevention
- Only call service-account endpoints for orgs where SM is confirmed enabled.
- Cache the user's SM-enabled org list and validate against it.
- Handle 404 on service-account endpoints by verifying SM enrollment.
When it happens
Trigger: GET /organizations/{organizationId}/service-accounts by a caller who does not have Secrets Manager access for the specified organization — SM not enabled on the org, or the token's claims don't include SM access for that org.
Common situations: Listing service accounts before SM is provisioned; using a personal API key that predates the org's SM enrollment; querying an org the user was removed from.
Related errors
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/6eefc6e522ddbac9.
Report an issue: GitHub.