RocketChat/Rocket.Chat · error · Meteor.Error
error-password-in-history
error-password-in-history
Error message
Entered password has been previously used
What it means
Password-history enforcement in saveUserProfile: if the user has services.passwordHistory and the new password matches one of the last Accounts_Password_History_Amount stored hashes (compareUserPasswordHistory returned false, meaning a history entry matched), the change is rejected. The feature is governed by Accounts_Password_History_Enabled.
Source
Thrown at apps/meteor/server/meteor-methods/users/saveUserProfile.ts:133
}
if (user && settings.email) {
await setEmailFunction(settings.email, user);
}
const canChangePasswordForOAuth = rcSettings.get<boolean>('Accounts_AllowPasswordChangeForOAuthUsers');
if (canChangePasswordForOAuth || user?.services?.password) {
// Should be the last check to prevent error when trying to check password for users without password
if (settings.newPassword && rcSettings.get<boolean>('Accounts_AllowPasswordChange') === true && user?.services?.password?.bcrypt) {
// don't let user change to same password
if (user && (await compareUserPassword(user, { plain: settings.newPassword }))) {
throw new Meteor.Error('error-password-same-as-current', 'Entered password same as current password', {
method: 'saveUserProfile',
});
}
if (user?.services?.passwordHistory && !(await compareUserPasswordHistory(user, { plain: settings.newPassword }))) {
throw new Meteor.Error('error-password-in-history', 'Entered password has been previously used', {
method: 'saveUserProfile',
});
}
passwordPolicy.validate(settings.newPassword);
await Accounts.setPasswordAsync(this.userId, settings.newPassword, {
logout: false,
});
if (user.requirePasswordChange) {
await Users.unsetRequirePasswordChange(user._id);
unset.requirePasswordChange = true;
unset.requirePasswordChangeReason = true;
}
await Users.addPasswordToHistory(
this.userId,View on GitHub (pinned to b2c16d5842)
Solutions
- Ask the user for a password they have not used recently and surface 'This password was used before' on error-password-in-history
- Review Accounts_Password_History_Enabled / Accounts_Password_History_Amount if the policy is stricter than intended
- In the UI, keep the error next to the new-password field so the user does not assume a typo
Defensive patterns
Strategy: try-catch
Validate before calling
// history is server-side; client can only enforce policy shape:
if (newPassword && newPassword === currentPassword) {
throw new Error('New password must differ from the current password');
} Try / catch
catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-password-in-history') {
showFieldError('newPassword', 'This password was used before - pick a new one');
}
} Prevention
- Tell users explicitly how many recent passwords are blocked (Accounts_Password_History_Amount) so they stop cycling
- Do not auto-generate and submit passwords in loops; each retry burns candidate values into user frustration
- Pair the catch with a password-manager-friendly error message instead of a generic failure
When it happens
Trigger: settings.newPassword reuses a password present in user.services.passwordHistory on a workspace where Accounts_Password_History_Enabled=true; the same-password check must pass first, and Accounts_AllowPasswordChange must be true.
Common situations: Enterprises enforcing no-reuse policies; users alternating between two favorite passwords; password managers re-suggesting recently used credentials.
Related errors
- error-password-same-as-current
- error-invalid-account
- error-invalid-password
- error-action-not-allowed
- error-could-not-change-email
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/1ad82cf211eafee7.
Report an issue: GitHub.