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

  1. Ask the user for a password they have not used recently and surface 'This password was used before' on error-password-in-history
  2. Review Accounts_Password_History_Enabled / Accounts_Password_History_Amount if the policy is stricter than intended
  3. 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

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


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/1ad82cf211eafee7. Report an issue: GitHub.