n8n-io/n8n · warning · BadRequestError

Invite links are not supported on this system, please use…

Error message

Invite links are not supported on this system, please use single sign on instead.

What it means

A BadRequestError (HTTP 400) from acceptInvitationWithToken when isSsoCurrentAuthenticationMethod() is true. Once the instance routes all authentication through SSO, invite-link-based signup is disabled because passwords are managed by the IdP. This is the token-acceptance counterpart of the invite-creation SSO block.

Solutions

  1. Direct the user to sign in via the SSO/Identity Provider instead of the invite link.
  2. If SSO was enabled in error, disable it and restart n8n, then the invite link will work again.
  3. Re-issue invites only after confirming SSO is off, or provision users through the IdP.
Defensive patterns

Strategy: validation

Validate before calling

// Check SSO state before showing the accept-invite UI.
const { ssoEnabled } = await api.get('/sso/config');
if (ssoEnabled) {
  redirect('/sso/login');
}

Type guard

function isSsoActive(c: { ssoEnabled: boolean }): boolean {
  return c.ssoEnabled === true;
}

Try / catch

try {
  await api.post('/accept-invitation', payload);
} catch (e) {
  if (e.response?.status === 400 && /single sign on/i.test(e.response.data.message)) {
    redirect('/sso/login');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: POST to the accept-invitation endpoint with an AcceptInvitationRequestDto while SSO/SAML is the current authentication method. The check is the first guard in the handler, before token validation.

Common situations: SSO was enabled after invites were sent; users received invite emails before the cutover and click them post-cutover; bookmarked invite links used after migration to SAML.

Related errors


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

Appendix: source

Thrown at packages/cli/src/controllers/invitation.controller.ts:173

	/**
	 * Fill out user shell with first name, last name, and password using JWT token.
	 */
	@Post('/accept', {
		skipAuth: true,
		// Two layered rate limit to ensure multiple users can accept an invitation from
		// the same IP address but aggressive per inviteeId limit.
		ipRateLimit: { limit: 100, windowMs: 1 * Time.minutes.toMilliseconds },
	})
	async acceptInvitationWithToken(
		req: AuthlessRequest,
		res: Response,
		@Body payload: AcceptInvitationRequestDto,
	) {
		if (isSsoCurrentAuthenticationMethod()) {
			this.logger.debug(
				'Invite links are not supported on this system, please use single sign on instead.',
			);
			throw new BadRequestError(
				'Invite links are not supported on this system, please use single sign on instead.',
			);
		}

		if (!payload.token) {
			this.logger.debug('Request to accept invitation failed because token is missing');
			throw new BadRequestError('Token is required');
		}

		const { firstName, lastName, password } = payload;

		// Extract inviterId and inviteeId from JWT token
		const { inviterId, inviteeId } = await this.userService.getInvitationIdsFromPayload(
			payload.token,
		);

		return await this.processInvitationAcceptance(
			inviterId,

View on GitHub (pinned to 5ac6606e81)