n8n-io/n8n · error · ForbiddenError
Admin cannot change role on global owner
Error message
Admin cannot change role on global owner
What it means
Returned by PATCH /users/:id/role when the requester's role.slug is GLOBAL_ADMIN_ROLE.slug AND the target's role.slug is GLOBAL_OWNER_ROLE.slug. Admins are not permitted to act on the global owner's role. Message is the NO_ADMIN_ON_OWNER constant. HTTP 403.
Source
Thrown at packages/cli/src/controllers/users.controller.ts:372
UsersController.ERROR_MESSAGES.CHANGE_ROLE;
if (req.user.id === id) {
throw new ForbiddenError(CANNOT_CHANGE_OWN_ROLE);
}
const targetUser = await this.userRepository.findOne({
where: { id },
relations: ['role'],
});
if (targetUser === null) {
throw new NotFoundError(NO_USER);
}
if (
req.user.role.slug === GLOBAL_ADMIN_ROLE.slug &&
targetUser.role.slug === GLOBAL_OWNER_ROLE.slug
) {
throw new ForbiddenError(NO_ADMIN_ON_OWNER);
}
if (
req.user.role.slug === GLOBAL_OWNER_ROLE.slug &&
targetUser.role.slug === GLOBAL_OWNER_ROLE.slug
) {
throw new ForbiddenError(NO_OWNER_ON_OWNER);
}
await this.userService.changeUserRole(targetUser, payload);
this.eventService.emit('user-changed-role', {
userId: req.user.id,
targetUserId: targetUser.id,
targetUserNewRole: payload.newRoleName,
publicApi: false,
});
View on GitHub (pinned to 5ac6606e81)
Solutions
- Only the current global owner (or the provisioning system) may reassign the owner role; use that path.
- Filter the owner out of any admin-driven role-batch operation.
- Surface a UI hint that the owner role cannot be changed by admins.
Defensive patterns
Strategy: validation
Validate before calling
function canChangeRole(requesterSlug: string, targetSlug: string) {
return !(requesterSlug === 'global:admin' && targetSlug === 'global:owner');
}
if (!canChangeRole(reqUser.role.slug, target.role.slug)) {
throw new Error('Admins cannot change the owner role');
} Type guard
const isAdmin = (s: string) => s === 'global:admin'; const isOwner = (s: string) => s === 'global:owner';
Try / catch
try { await fetch(`/rest/users/${id}/role`, { method: 'PATCH', body }); }
catch (e) { if (e.statusCode === 403 && /change role on global owner/.test(e.message)) { /* route to owner */ } else throw e; } Prevention
- Filter global:owner out of admin role-change targets.
- Use the ownership-transfer flow to reassign the owner role.
- Surface role badges so admins can see owner rows distinctly.
When it happens
Trigger: A global admin calls PATCH /users/<owner-id>/role; both role-slug comparisons match.
Common situations: Admin console where the owner is listed alongside admins; scripted role sync that includes the owner id; misconfiguration granting admin rights to a service account that then targets the owner.
Related errors
- Admin cannot reset password of global owner
- Owner cannot change role on global owner
- Instance owner cannot be deleted.
- Cannot change your own global role
- Instance roles are managed automatically and cannot be chang
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/1aa6fc17f92526d3.
Report an issue: GitHub.