RocketChat/Rocket.Chat · error · Meteor.Error

error-app-user-is-not-allowed-to-login

error-app-user-is-not-allowed-to-login

Error message

App user is not allowed to login

What it means

Accounts.validateLoginAttempt throws error-app-user-is-not-allowed-to-login when the authenticating account has type 'app'. Users with type 'app' are internal service accounts created by the Apps Engine (bots), and Rocket.Chat forbids them from establishing interactive login sessions. The check runs after the IP/user block checks, once login.allowed is true.

Source

Thrown at apps/meteor/server/lib/auth/startup.js:433

		});
	}

	if (!(await isValidAttemptByUser(login))) {
		throw new Meteor.Error('error-login-blocked-for-user', 'Login has been temporarily blocked For User', {
			function: 'Accounts.validateLoginAttempt',
		});
	}

	if (login.allowed !== true) {
		return login.allowed;
	}

	if (login.user.type === 'visitor') {
		return true;
	}

	if (login.user.type === 'app') {
		throw new Meteor.Error('error-app-user-is-not-allowed-to-login', 'App user is not allowed to login', {
			function: 'Accounts.validateLoginAttempt',
		});
	}

	if (!!login.user.active !== true) {
		throw new Meteor.Error('error-user-is-not-activated', 'User is not activated', {
			function: 'Accounts.validateLoginAttempt',
		});
	}

	if (!login.user.roles || !Array.isArray(login.user.roles)) {
		throw new Meteor.Error('error-user-has-no-roles', 'User has no roles', {
			function: 'Accounts.validateLoginAttempt',
		});
	}

	if (login.user.roles.includes('admin') === false && login.type === 'password' && settings.get('Accounts_EmailVerification') === true) {
		const validEmail = login.user.emails.filter((email) => email.verified === true);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Create a dedicated normal user (type 'user') for scripts/integrations and use its credentials or a personal access token
  2. If the account should be human, repair the document: set type back to 'user' in the Users collection / admin user edit
  3. Never use Apps Engine bot credentials for interactive login flows

Example fix

// before
await sdk.login({ user: 'my-bot.user', password: '...' });
// bot has type 'app' -> error-app-user-is-not-allowed-to-login

// after
// create a normal integration user, then:
await sdk.login({ user: 'integration.user', password: '...' });
// or authenticate with headers: X-Auth-Token + X-User-Id (personal access token)
Defensive patterns

Strategy: validation

Validate before calling

const canLoginInteractively = (user: { type?: string } | null | undefined): boolean =>
  !!user && user.type !== 'app';

const account = await Users.findOneByUsername(username);
if (!canLoginInteractively(account)) {
  throw new Error('App users cannot log in interactively; use a normal user or a personal access token');
}

Type guard

const isAppUser = (u: { type?: string } | null | undefined): u is { type: 'app' } =>
  u?.type === 'app';

Try / catch

try {
  await login(user, password);
} catch (e) {
  if (e instanceof Meteor.Error && e.error === 'error-app-user-is-not-allowed-to-login') {
    // permanent: switch to a non-app account or token-based auth
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling LoginWithPassword / POST /api/v1/login or any interactive auth flow with the credentials of a bot user whose user.type === 'app'; scripts, load tests, or dashboards reusing app-user credentials.

Common situations: Teams reuse the bot account's username/password for automation instead of creating a dedicated user; a human account was wrongly flagged type 'app' by a bad data import; the app user was re-created by the Apps Engine after an app reinstall.

Related errors


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