n8n-io/n8n · warning · ForbiddenError

This account is managed via environment variables and cannot

Error message

This account is managed via environment variables and cannot be modified through the API

What it means

A ForbiddenError (HTTP 403) from the PATCH /me (updateProfile) handler when isUserManagedByEnv(req.user) returns true. The owner account is bound to environment variables (ownerManagedByEnv with a matching ownerEmail), so its profile cannot be edited through the API — the source of truth is the env config. Returns 403 because the action is forbidden by configuration, not a bad request.

Source

Thrown at packages/cli/src/controllers/me.controller.ts:61

	/**
	 * Update the logged-in user's properties, except password.
	 */
	@Patch('/')
	async updateCurrentUser(
		req: AuthenticatedRequest,
		res: Response,
		@Body payload: UserUpdateRequestDto,
	): Promise<PublicUser> {
		const {
			id: userId,
			email: currentEmail,
			firstName: currentFirstName,
			lastName: currentLastName,
		} = req.user;

		if (this.isUserManagedByEnv(req.user)) {
			throw new ForbiddenError(
				'This account is managed via environment variables and cannot be modified through the API',
			);
		}

		const { currentPassword, ...payloadWithoutPassword } = payload;
		const { email, firstName, lastName } = payload;
		const isEmailBeingChanged = email !== currentEmail;
		const isFirstNameChanged = firstName !== currentFirstName;
		const isLastNameChanged = lastName !== currentLastName;

		// Check if the user is authenticated via SSO - they cannot change their profile info
		if (isEmailBeingChanged || isFirstNameChanged || isLastNameChanged) {
			const ssoIdentity = await this.userService.findSsoIdentity(userId);

			if (ssoIdentity && this.isAuthIdentityActive(ssoIdentity)) {
				this.logger.debug(
					`Request to update user failed because ${ssoIdentity.providerType} user may not change their profile information`,
					{

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Update the owner profile by changing the relevant environment variables and restarting n8n.
  2. If API edits are required, disable ownerManagedByEnv in the config and manage the owner via the DB/API.
  3. Use a different (non-owner) account for profile edits via the API.
Defensive patterns

Strategy: validation

Validate before calling

// Detect env-managed owner before allowing profile edits.
const me = await api.get('/me');
const ownerManagedByEnv = me.flags?.ownerManagedByEnv ?? false;
if (ownerManagedByEnv && me.role === 'global:owner') {
  throw new Error('Owner profile is env-managed; edit via environment variables.');
}

Type guard

function isEnvManagedOwner(u: { role: string; email: string }, cfg: { ownerManagedByEnv: boolean; ownerEmail: string }): boolean {
  return cfg.ownerManagedByEnv
    && u.role === 'global:owner'
    && u.email.toLowerCase() === cfg.ownerEmail.toLowerCase();
}

Try / catch

try {
  await api.patch('/me', payload);
} catch (e) {
  if (e.response?.status === 403 && /environment variables/i.test(e.response.data.message)) {
    notify('Edit this account via environment variables, not the API.');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: PATCH /me changing email/firstName/lastName/password for the owner user when N8N_USER_MANAGEMENT_JWT_SECRET / owner env vars (N8N_OWNER_EMAIL etc.) are set and the requesting user's email matches the configured owner email.

Common situations: Self-hosted deployments that pin the owner via env vars for GitOps/immutability; an operator tries to rename the owner email through the UI; a Docker deploy with N8N_OWNER_EMAIL set.

Related errors


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