n8n-io/n8n · warning · ForbiddenError
Cannot invite admin user without advanced permissions. Pleas
Error message
Cannot invite admin user without advanced permissions. Please upgrade to a license that includes this feature.
What it means
A ForbiddenError (HTTP 403) thrown inside the invitations.map() when a requested role is 'global:admin' but this.license.isAdvancedPermissionsLicensed() returns false. Admin-level invitations require the advanced-permissions license feature; without it the request is rejected even if seats remain. It is a license-gate, not a validation error, so it returns 403.
Source
Thrown at packages/cli/src/controllers/invitation.controller.ts:78
}
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 };
});
const { usersInvited, usersCreated } = await this.userService.inviteUsers(req.user, attributes);
await this.externalHooks.run('user.invited', [usersCreated]);
return usersInvited;
}
/**
* Process invitation acceptance: validate users, update invitee, and handle authentication.
*/
private async processInvitationAcceptance(
inviterId: string,View on GitHub (pinned to 5ac6606e81)
Solutions
- Upgrade to a license that includes advanced permissions before inviting admins.
- Change the invite role to 'global:member' or another role allowed by the current license.
- Verify the license entitlement via GET /license or the Admin UI > License before retrying.
Example fix
// before
await api.post('/invite', [{ email, role: 'global:admin' }]);
// after: downgrade role when license lacks advanced permissions
const role = license.hasAdvancedPermissions ? 'global:admin' : 'global:member';
await api.post('/invite', [{ email, role }]); Defensive patterns
Strategy: validation
Validate before calling
// Check advanced-permissions entitlement before inviting an admin.
const license = await api.get('/license');
const canInviteAdmin = license.features.includes('feat:advancedPermissions');
const role = canInviteAdmin ? 'global:admin' : 'global:member'; Type guard
function canInviteAdminRole(license: { features: string[] }): boolean {
return license.features.includes('feat:advancedPermissions');
} Try / catch
try {
await api.post('/invite', [{ email, role: 'global:admin' }]);
} catch (e) {
if (e.response?.status === 403 && /advanced permissions/i.test(e.response.data.message)) {
// downgrade role or prompt upgrade
await api.post('/invite', [{ email, role: 'global:member' }]);
return;
}
throw e;
} Prevention
- Query license entitlements before offering the admin role in the invite UI.
- Disable the admin-role dropdown when advanced permissions are absent.
- Plan license tier to match the number of admins needed.
When it happens
Trigger: POST /invite with one or more entries whose role is 'global:admin' on an instance whose license does not include advanced permissions (e.g. Starter or a community-licensed install). The check fires per-invite during the attributes mapping, after owner and quota checks pass.
Common situations: Downgrading a license from Enterprise to a lower tier that drops advanced permissions; inviting an admin on a trial that expired; scripting invites with role: 'global:admin' against a non-licensed instance.
Related errors
- Maximum number of users reached
- Admin cannot reset password of global owner
- Admin cannot change role on global owner
- Maximum number of users reached
- Your instance is not licensed to use role "${role}".
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/fe98dce51b8afdc7.
Report an issue: GitHub.