n8n-io/n8n · warning · ForbiddenError

Maximum number of users reached

Error message

Maximum number of users reached

What it means

A ForbiddenError (HTTP 403) thrown when this.license.isWithinUsersLimit() returns false at invite time. The message comes from the shared constant RESPONSE_ERROR_MESSAGES.USERS_QUOTA_REACHED ('Maximum number of users reached'). The license seats or the hard user cap has been exhausted, so no new invited users can be created.

Source

Thrown at packages/cli/src/controllers/invitation.controller.ts:66

	) {
		if (invitations.length === 0) return [];

		const isWithinUsersLimit = this.license.isWithinUsersLimit();

		if (isSsoCurrentAuthenticationMethod()) {
			this.logger.debug(
				'SSO is enabled, so users are managed by the Identity Provider and cannot be added through invites',
			);
			throw new BadRequestError(
				'SSO is enabled, so users are managed by the Identity Provider and cannot be added through invites',
			);
		}

		if (!isWithinUsersLimit) {
			this.logger.debug(
				'Request to send email invite(s) to user(s) failed because the user limit quota has been reached',
			);
			throw new ForbiddenError(RESPONSE_ERROR_MESSAGES.USERS_QUOTA_REACHED);
		}

		if (!(await this.ownershipService.hasInstanceOwner())) {
			this.logger.debug(
				'Request to send email invite(s) to user(s) failed because the owner account is not set up',
			);
			throw new BadRequestError('You must set up your own account before inviting others');
		}

		const attributes = invitations.map(({ email, role }) => {
			if (role === 'global:admin' && !this.license.isAdvancedPermissionsLicensed()) {
				throw new ForbiddenError(
					'Cannot invite admin user without advanced permissions. Please upgrade to a license that includes this feature.',
				);
			}
			return { email, role };
		});

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Upgrade the license to add more seats, or remove/deactivate existing users to free seats.
  2. Audit active users via the Admin UI > Users and delete users who no longer need access.
  3. If on Cloud, increase the plan tier in the billing portal.
  4. Re-check with this.license.isWithinUsersLimit() (or GET /license) before retrying the invite.
Defensive patterns

Strategy: validation

Validate before calling

// Verify seat availability before inviting.
const license = await api.get('/license');
if (license.seatsUsed >= license.seatsLimit) {
  throw new Error('User quota reached — upgrade or remove users.');
}

Type guard

function hasFreeSeats(l: { seatsUsed: number; seatsLimit: number }): boolean {
  return l.seatsUsed < l.seatsLimit;
}

Try / catch

try {
  await api.post('/invite', invites);
} catch (e) {
  if (e.response?.status === 403 && /quota/i.test(e.response.data.message)) {
    promptUpgradeOrCleanup();
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /invite when the active license's seat count is at or above the limit, or when running without a license and the free-tier active-user cap is reached. Checked after the SSO block, before the owner-exists check.

Common situations: Self-hosted instance on a fixed-seat enterprise license that has been fully assigned; Cloud plan at its user cap; team grew beyond the purchased tier; deactivated-but-not-deleted users still counting against the quota.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/164264961b518c61. Report an issue: GitHub.