bitwarden/server · error · BadRequestException
Cipher was not unarchived. Ensure the provided ID is correct
Error message
Cipher was not unarchived. Ensure the provided ID is correct and you have permission to archive it.
What it means
PUT /ciphers/{id}/unarchive (PutUnarchive) delegates to UnarchiveManyAsync with a single id. If zero ciphers are unarchived — wrong id, not owned, no permission, or the cipher isn't archived — the server returns HTTP 400. (Note: the message text erroneously says 'archive it' rather than 'unarchive it', but the cause is the unarchive operation.)
Source
Thrown at src/Api/Vault/Controllers/CiphersController.cs:1092
!await CanDeleteOrRestoreCipherAsAdminAsync(new Guid(model.OrganizationId), cipherIds))
{
throw new NotFoundException();
}
var userId = _userService.GetProperUserId(User).Value;
await _cipherService.SoftDeleteManyAsync(cipherIds, userId, new Guid(model.OrganizationId), true);
}
[HttpPut("{id}/unarchive")]
public async Task<CipherResponseModel> PutUnarchive(Guid id)
{
var userId = _userService.GetProperUserId(User).Value;
var unarchivedCipherDetails = await _unarchiveCiphersCommand.UnarchiveManyAsync([id], userId);
if (unarchivedCipherDetails.Count == 0)
{
throw new BadRequestException("Cipher was not unarchived. Ensure the provided ID is correct and you have permission to archive it.");
}
var unarchivedCipher = unarchivedCipherDetails.First();
return new CipherResponseModel(unarchivedCipher,
await _userService.GetUserByPrincipalAsync(User),
await GetOrganizationAbilityAsync(unarchivedCipher),
_globalSettings
);
}
[HttpPut("unarchive")]
public async Task<ListResponseModel<CipherResponseModel>> PutUnarchiveMany([FromBody] CipherBulkUnarchiveRequestModel model)
{
if (!_globalSettings.SelfHosted && model.Ids.Count() > 500)
{
throw new BadRequestException("You can only unarchive up to 500 items at a time.");
}
View on GitHub (pinned to e93b962371)
Solutions
- Verify the cipher id is correct, owned/editable, and is actually in an archived state.
- Re-sync the vault to refresh cipher state before retrying.
- For org ciphers, confirm edit permission on the relevant collection.
Defensive patterns
Strategy: validation
Validate before calling
async function safeUnarchive(id) {
const c = await api.get(`/ciphers/${id}`).catch(() => null);
if (!c || !c.editable) throw new Error('Cipher missing or not editable; cannot unarchive');
return api.put(`/ciphers/${id}/unarchive`);
} Type guard
function isUnarchivable(cipher: { id?: string; editable?: boolean; deletedDate?: string | null } | null): boolean {
return !!cipher && !!cipher.id && cipher.editable === true && !cipher.deletedDate;
} Try / catch
try { await api.put(`/ciphers/${id}/unarchive`); }
catch (e) {
if (e?.response?.status === 400 && /not unarchived/i.test(e.response.data?.message ?? '')) {
await syncVault(); // verify state/permissions; note the server message erroneously says 'archive'
} else throw e;
} Prevention
- Confirm the cipher is actually archived and you can edit it before unarchiving.
- Re-sync to refresh state; the item may have been permanently deleted.
- Check org/collection edit rights for org ciphers.
When it happens
Trigger: PUT /ciphers/{id}/unarchive where the id does not exist, belongs to another user, lacks permission, or is not currently archived.
Common situations: Unarchiving a cipher that was permanently deleted by another client; unarchiving an org cipher without edit rights; a stale cipher id after sync.
Related errors
- Cipher was not archived. Ensure the provided ID is correct a
- No ciphers were archived. Ensure the provided IDs are correc
- You can only unarchive up to 500 items at a time.
- Cipher was not encrypted for the current user. Please try ag
- Organization mismatch. Re-sync if you recently moved this it
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/9965a23df2c66228.
Report an issue: GitHub.