n8n-io/n8n · error · ForbiddenError
Login is handled by ${currentAuthenticationMethod}. Please c
Error message
Login is handled by ${currentAuthenticationMethod}. Please contact your Identity Provider to reset your password. What it means
POST /rest/forgot-password is refused when SAML or OIDC is the current authentication method AND the user lacks the `user:resetPassword` global scope AND has not opted into `settings.allowSSOManualLogin`. Password resets are delegated to the identity provider in SSO mode; n8n will not issue a local reset token.
Source
Thrown at packages/cli/src/controllers/password-reset.controller.ts:109
return;
}
if (user.role.slug !== GLOBAL_OWNER_ROLE.slug && !this.license.isWithinUsersLimit()) {
this.logger.debug(
'Request to send password reset email failed because the user limit was reached',
);
throw new ForbiddenError(RESPONSE_ERROR_MESSAGES.USERS_QUOTA_REACHED);
}
if (
(isSamlCurrentAuthenticationMethod() || isOidcCurrentAuthenticationMethod()) &&
!(hasGlobalScope(user, 'user:resetPassword') || user.settings?.allowSSOManualLogin === true)
) {
const currentAuthenticationMethod = isSamlCurrentAuthenticationMethod() ? 'SAML' : 'OIDC';
this.logger.debug(
`Request to send password reset email failed because login is handled by ${currentAuthenticationMethod}`,
);
throw new ForbiddenError(
`Login is handled by ${currentAuthenticationMethod}. Please contact your Identity Provider to reset your password.`,
);
}
const ldapIdentity = user.authIdentities?.find((i) => i.providerType === 'ldap');
if (!user.password || (ldapIdentity && user.disabled)) {
this.logger.debug(
'Request to send password reset email failed because no user was found for the provided email',
{ invalidEmail: email },
);
return;
}
if (this.license.isLdapEnabled() && ldapIdentity) {
throw new UnprocessableRequestError('forgotPassword.ldapUserPasswordResetUnavailable');
}
const url = this.authService.generatePasswordResetUrl(user);View on GitHub (pinned to 5ac6606e81)
Solutions
- Direct the user to the identity provider's self-service password reset.
- If local reset must stay available, grant the user the `user:resetPassword` global scope or set `allowSSOManualLogin: true` in their settings.
- Confirm the intended auth method — if SSO was enabled by mistake, switch back via config.
Defensive patterns
Strategy: validation
Validate before calling
// If SSO is the auth method, route to the IdP unless the user has reset scope or manual login.
const ssoActive = settings.authMethod === 'saml' || settings.authMethod === 'oidc';
if (ssoActive && !me.canResetPassword && !me.allowSSOManualLogin) {
redirectToIdpReset();
return;
}
await restApi.post('/forgot-password', { email }); Try / catch
try {
await restApi.post('/forgot-password', { email });
} catch (e) {
if (e.response?.status === 403 && /login is handled by/i.test(e.response.data.message)) {
showIdpRedirectNotice(e.response.data.message);
} else throw e;
} Prevention
- Detect SSO mode from settings and hide the local forgot-password link for SSO-only users.
- Grant `user:resetPassword` scope (or set allowSSOManualLogin) for users who need a local reset fallback.
- Document the IdP self-service reset URL for SSO users.
When it happens
Trigger: forgotPassword when `isSamlCurrentAuthenticationMethod()` or `isOidcCurrentAuthenticationMethod()` is true, the user has no `user:resetPassword` scope, and `user.settings.allowSSOManualLogin !== true`.
Common situations: SSO migration where users still try the local forgot-password link; an SSO-only user without manual-login allowance; admin hasn't granted the reset scope.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- 401
- forgotPassword.ldapUserPasswordResetUnavailable
- SSO is enabled, so users are managed by the Identity Provide
- Invite links are not supported on this system, please use si
- ${ssoIdentity.providerType.toUpperCase()} user may not chang
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f17e954924c9cafa.
Report an issue: GitHub.