bitwarden/server · error · NotFoundException
Resource not found.
Error message
Resource not found.
What it means
Thrown at SecretsManagerPortingController.cs:45 inside Export (GET sm/{org}/export). The caller is not an OrganizationAdmin for that org OR lacks Secrets Manager access (_currentContext.AccessSecretsManager false). Either condition throws NotFoundException -> HTTP 404. Export is restricted to organization admins with SM access.
Source
Thrown at src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs:45
public SecretsManagerPortingController(ISecretRepository secretRepository, IProjectRepository projectRepository,
IUserService userService, IMaxProjectsQuery maxProjectsQuery, IImportCommand importCommand,
ICurrentContext currentContext)
{
_secretRepository = secretRepository;
_projectRepository = projectRepository;
_userService = userService;
_maxProjectsQuery = maxProjectsQuery;
_importCommand = importCommand;
_currentContext = currentContext;
}
[HttpGet("sm/{organizationId}/export")]
public async Task<SMExportResponseModel> Export([FromRoute] Guid organizationId)
{
if (!await _currentContext.OrganizationAdmin(organizationId) || !_currentContext.AccessSecretsManager(organizationId))
{
throw new NotFoundException();
}
var userId = _userService.GetProperUserId(User).Value;
var projects = await _projectRepository.GetManyByOrganizationIdAsync(organizationId, userId, AccessClientType.NoAccessCheck);
var secrets = await _secretRepository.GetManyDetailsByOrganizationIdAsync(organizationId, userId, AccessClientType.NoAccessCheck);
if (projects == null && secrets == null)
{
throw new NotFoundException();
}
return new SMExportResponseModel(projects.Select(p => p.Project), secrets.Select(s => s.Secret));
}
[HttpPost("sm/{organizationId}/import")]
public async Task Import([FromRoute] Guid organizationId, [FromBody] SMImportRequestModel importRequest)
{
if (!await _currentContext.OrganizationAdmin(organizationId) || !_currentContext.AccessSecretsManager(organizationId))View on GitHub (pinned to e93b962371)
Solutions
- Run the export as an organization admin who also has Secrets Manager access.
- Use an admin-level API token for automated exports.
- Confirm the organization has Secrets Manager enabled for the admin.
Example fix
// before: non-admin token attempts export
await memberClient.GetAsync($"/sm/{orgId}/export"); // 404
// after: use an admin credential
var adminClient = ClientFor(orgAdminCredential);
await adminClient.GetAsync($"/sm/{orgId}/export"); Defensive patterns
Strategy: validation
Validate before calling
if (!await IsOrganizationAdminAsync(orgId) || !await HasSecretsManagerAccessAsync(orgId))
throw new UnauthorizedAccessException("Export requires org admin with SM access");
await adminClient.GetAsync($"/sm/{orgId}/export"); Try / catch
try { await client.GetAsync($"/sm/{orgId}/export"); }
catch (ApiException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { Log.Warn("Export denied; use an admin with SM access"); } Prevention
- Use an admin API token for automated exports.
- Verify the caller is an org admin before exposing the export action.
- Confirm SM is enabled on the org.
When it happens
Trigger: GET /sm/{orgId}/export by a non-admin SM user, a standard org member, or an admin without the Secrets Manager add-on/access.
Common situations: A custom-role or standard user attempts an export; admin whose SM access was revoked; scripted export run with a non-admin token.
Related errors
- Unauthorized.
- Resource not found.
- Resource not found.
- Resource not found.
- Last synced date must be in the past.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/8a93600614bb2aea.
Report an issue: GitHub.