bitwarden/server · error · BadRequestException
Cipher was not encrypted for the current user. Please try ag
Error message
Cipher was not encrypted for the current user. Please try again.
What it means
POST /ciphers (Post) checks that the request body's `EncryptedFor` matches the authenticated user's id. EncryptedFor records which user's key the cipher was encrypted for; a mismatch means the server cannot decrypt the payload and rejects it as HTTP 400. This guards against stale/multi-account clients encrypting for the wrong user.
Source
Thrown at src/Api/Vault/Controllers/CiphersController.cs:174
GetOrganizationAbility(cipher, organizationAbilities),
_globalSettings,
collectionCiphersGroupDict)).ToArray();
return new ListResponseModel<CipherDetailsResponseModel>(responses);
}
[HttpPost("")]
public async Task<CipherResponseModel> Post([FromBody] CipherRequestModel model)
{
var user = await _userService.GetUserByPrincipalAsync(User);
// Validate the model was encrypted for the posting user
if (model.EncryptedFor != null)
{
if (model.EncryptedFor != user.Id)
{
_logger.LogError("Cipher was not encrypted for the current user. CurrentUser: {CurrentUserId}, EncryptedFor: {EncryptedFor}", user.Id, model.EncryptedFor);
throw new BadRequestException("Cipher was not encrypted for the current user. Please try again.");
}
}
var cipher = model.ToCipherDetails(user.Id);
if (cipher.OrganizationId.HasValue && !await _currentContext.OrganizationUser(cipher.OrganizationId.Value))
{
throw new NotFoundException();
}
await _cipherService.SaveDetailsAsync(cipher, user.Id, model.LastKnownRevisionDate, null, cipher.OrganizationId.HasValue);
var response = new CipherResponseModel(cipher, user, await GetOrganizationAbilityAsync(cipher), _globalSettings);
return response;
}
[HttpPost("create")]
public async Task<CipherResponseModel> PostCreate([FromBody] CipherCreateRequestModel model)
{
var user = await _userService.GetUserByPrincipalAsync(User);View on GitHub (pinned to e93b962371)
Solutions
- Ensure the client encrypts the cipher key with the currently-authenticated user's key and sets EncryptedFor to that user's id.
- Re-sync or log out and back in to refresh the active user context before retrying.
- Verify the active account id before constructing the request payload.
Example fix
// before
POST /ciphers body: { "encryptedFor": "<oldUserGuid>", ... }
// after
POST /ciphers body: { "encryptedFor": "<currentActiveUserGuid>", ... } Defensive patterns
Strategy: validation
Validate before calling
function buildCipherPayload(activeUserId, cipher) {
if (cipher.encryptedFor != null && cipher.encryptedFor !== activeUserId) {
throw new Error('cipher.encryptedFor must match the active user id');
}
return { ...cipher, encryptedFor: activeUserId };
} Type guard
function isEncryptedForUser(payload: { encryptedFor?: string | null }, userId: string): boolean {
return payload.encryptedFor == null || payload.encryptedFor === userId;
} Try / catch
try { await api.post('/ciphers', payload); }
catch (e) {
if (e?.response?.status === 400 && /encrypted for the current user/i.test(e.response.data?.message ?? '')) {
await resyncActiveAccount(); // refresh user context, then retry once
} else throw e;
} Prevention
- Derive EncryptedFor from the active account, never cache it.
- In multi-account clients, re-encrypt when the active account changes.
- Re-sync or re-login on session staleness before editing.
When it happens
Trigger: POST /ciphers where `model.EncryptedFor` is set to a user id other than the currently authenticated user (e.g. an account switch without re-encryption, or a replayed request under a different account).
Common situations: Multi-account clients (web/desktop) where the active account differs from the account whose key was used; a stale session after re-login; replaying a captured request as another user.
Related errors
- The model state is invalid.
- AccountKeys are only supported for V2 encryption.
- All existing trusted devices must be included in the rotatio
- All existing emergency access keys must be included in the r
- All existing folders must be included in the rotation.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/9682361876254eb3.
Report an issue: GitHub.