{"record":{"id":"7efb7cd71059529f","repo":"toeverything/AFFiNE","slug":"invalid-email-7efb7c","errorCode":"invalid_email","errorMessage":"An invalid email provided: ${email}","messagePattern":"An invalid email provided: (.+?)","errorType":"exception","errorClass":"InvalidEmail","httpStatus":400,"severity":"error","filePath":"packages/backend/server/src/core/auth/magic-link.ts","lineNumber":143,"sourceCode":"      throw new InvalidEmailToken();\n    }\n\n    const user = await this.models.user.fulfill(email);\n\n    return { userId: user.id, method: 'magic_link' };\n  }\n\n  private async assertSignupAllowed(email: string) {\n    if (!this.config.auth.allowSignup) {\n      throw new SignUpForbidden();\n    }\n\n    if (!this.config.auth.requireEmailDomainVerification) {\n      return;\n    }\n\n    if (!(await verifyEmailDomainRecords(email))) {\n      throw new InvalidEmail({ email });\n    }\n  }\n}\n","sourceCodeStart":125,"sourceCodeEnd":147,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/core/auth/magic-link.ts#L125-L147","documentation":"When config.auth.requireEmailDomainVerification is enabled, assertSignupAllowed additionally calls verifyEmailDomainRecords(email), which checks the email domain's DNS records. Failure throws InvalidEmail (invalid_email, 'An invalid email provided'). Only new (unknown) users reach this check - existing users skip it.","triggerScenarios":"Signing up from a domain without the required MX/TXT records AFFiNE expects; DNS not yet propagated after domain setup; typo'd domain (example.co vs example.com); corporate domains with restrictive or missing MX records; resolvers returning SERVFAIL.","commonSituations":"Self-hosted instances that turned on domain verification; newly purchased domains; internal-only domains without public DNS; verifying from a network with filtered DNS.","solutions":["Fix the domain's DNS records (MX/verification TXT) as required by your instance's domain verification setup","Use an email address on an already-verified domain","Wait for DNS propagation and retry with a fresh request","Admins: disable requireEmailDomainVerification if the check is not needed for your deployment"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function isEmailDomainReady(email: string): Promise<boolean> {\n  const domain = email.split('@')[1];\n  try {\n    const mx = await dns.resolveMx(domain);\n    return mx.length > 0;\n  } catch {\n    return false;\n}\n}","typeGuard":null,"tryCatchPattern":"try {\n  await sendMagicLink(email);\n} catch (e) {\n  if (isAffineErrorCode(e, 'invalid_email')) {\n    show('Your email domain is not verified for this workspace. Use a verified domain.');\n  } else throw e;\n}","preventionTips":["Verify domain DNS (MX/records) before enabling requireEmailDomainVerification","Collect allowed domains up front and check the signup form against them"],"tags":["auth","signup","email","dns","configuration"],"backgroundTag":"email-domain-verification-failed","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}