toeverything/AFFiNE · error · InvalidEmail

invalid_email

invalid_email

Error message

An invalid email provided: ${email}

What it means

In assertSignupAllowed, after allowSignup passes, if config.auth.requireEmailDomainVerification is true the server runs verifyEmailDomainRecords(email) which checks DNS records (MX/TXT) for the email's domain. If verification fails, InvalidEmail is thrown with the email. This is an email-domain allowlisting mechanism: only emails from domains with the expected DNS records can self-register.

Source

Thrown at packages/backend/server/src/core/auth/magic-link.ts:143

      throw new InvalidEmailToken();
    }

    const user = await this.models.user.fulfill(email);

    return { userId: user.id, method: 'magic_link' };
  }

  private async assertSignupAllowed(email: string) {
    if (!this.config.auth.allowSignup) {
      throw new SignUpForbidden();
    }

    if (!this.config.auth.requireEmailDomainVerification) {
      return;
    }

    if (!(await verifyEmailDomainRecords(email))) {
      throw new InvalidEmail({ email });
    }
  }
}

View on GitHub (pinned to 26c515e050)

Solutions

  1. Use an email address whose domain has the required DNS verification records, or have an admin pre-create the account.
  2. Publish the expected DNS (MX/TXT) records for the target domain and re-try after propagation.
  3. If domain verification is not needed, set config.auth.requireEmailDomainVerification=false.
  4. Check server-side DNS resolution if the domain should be valid but verification fails intermittently.
Defensive patterns

Strategy: validation

Type guard

function isInvalidEmail(err: unknown): boolean {
  return (
    !!err &&
    typeof err === 'object' &&
    (err as { code?: string }).code === 'invalid_email'
  );
}

Try / catch

try {
  await magicLink.send(email);
} catch (err) {
  if (isInvalidEmail(err)) {
    showUser('This email domain is not allowed. Contact your administrator.');
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: config.auth.requireEmailDomainVerification === true AND no existing user AND the email's domain DNS records do not satisfy verifyEmailDomainRecords (missing/incorrect MX or TXT records, DNS lookup failure, transient network error resolving DNS).

Common situations: Self-hosted org that restricts signups to corporate domains but the user's email is on a public provider (gmail) or an unverified domain. DNS records were never published. A transient DNS resolution failure on the server caused verification to fail.

Related errors


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/7efb7cd71059529f. Report an issue: GitHub.