RocketChat/Rocket.Chat · error · MeteorError

error-license-user-limit-reached

error-license-user-limit-reached

Error message

error-license-user-limit-reached

What it means

Thrown by the 'beforeActivateUser' callback when the enterprise license's active-user allowance is exhausted (License.shouldPreventAction('activeUsers') resolves true). Rocket.Chat EE counts every active (non-deactivated) user against the license's maxActiveUsers limit, and activating one more user would exceed it. The same guard also fires from validateUserRoles when a user transitions to active. It is a hard business-limit stop, not a bug.

Solutions

  1. Deactivate inactive users until the active count is below the licensed limit, then retry the activation
  2. Check the license status and limit in Administration > License (or GET /api/v1/license.get) and apply a license with a higher maxActiveUsers
  3. If the license was recently renewed but the error persists, restart the server / verify the license payload was applied so the in-memory limits refresh
  4. For migrations, deactivate users before import and activate them in batches under the limit

Example fix

// before: activating while at the limit throws error-license-user-limit-reached
await Meteor.callAsync('insertOrUpdateUser', { ...userData, active: true });

// after: pre-check the license gate the same way the hook does
import { License } from '@rocket.chat/license';
if (await License.shouldPreventAction('activeUsers')) {
  // stay under the limit first: deactivate another user or upgrade the license
  throw new Error('Cannot activate: active-user limit reached');
}
await Meteor.callAsync('insertOrUpdateUser', { ...userData, active: true });
Defensive patterns

Strategy: validation

Validate before calling

import { License } from '@rocket.chat/license';

const canActivate = async (): Promise<boolean> => !(await License.shouldPreventAction('activeUsers'));

Try / catch

try {
  await Meteor.callAsync('insertOrUpdateUser', user);
} catch (err: any) {
  if (err?.error === 'error-license-user-limit-reached' || err?.message === 'error-license-user-limit-reached') {
    // reduce active users or upgrade license, then surface a billing prompt
  }
  throw err;
}

Prevention

When it happens

Trigger: An admin activates a deactivated user, saves a user with active !== false for the first time, or a new user registers/SSO-logs-in while activeUsers count >= the licensed max. Also triggered by insertOrUpdateUser flows (admin UI, REST API user creation, LDAP sync setting users active).

Common situations: Expired or trial license after the org grew; imported a large user base during migration; LDAP provisioning activating dormant accounts; license renewed with fewer seats than current active users.

Related errors


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

Appendix: source

Thrown at apps/meteor/ee/server/hooks/auth/callback.ts:50

		callbacks.priority.HIGH,
		'validateUserRoles',
	);

	callbacks.add(
		'afterDeactivateUser',
		async (user) => {
			await License.shouldPreventAction('activeUsers');
			return user;
		},
		callbacks.priority.HIGH,
		'validateUserStatus',
	);

	callbacks.add(
		'beforeActivateUser',
		async () => {
			if (await License.shouldPreventAction('activeUsers')) {
				throw new MeteorError('error-license-user-limit-reached', i18n.t('error-license-user-limit-reached'));
			}
			return undefined;
		},
		callbacks.priority.HIGH,
		'validateUserStatus',
	);
});

License.onInvalidate(() => {
	callbacks.remove('beforeSaveUser', 'validateUserRoles');
	callbacks.remove('afterSaveUser', 'validateUserRoles');
	callbacks.remove('afterDeleteUser', 'validateUserRoles');

	callbacks.remove('afterDeactivateUser', 'validateUserStatus');
	callbacks.remove('beforeActivateUser', 'validateUserStatus');
});

View on GitHub (pinned to b2c16d5842)