toeverything/AFFiNE · error · InvalidEmail
invalid_email
invalid_email
Error message
An invalid email provided: ${email} What it means
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.
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
Defensive patterns
Strategy: validation
Validate before calling
async function isEmailDomainReady(email: string): Promise<boolean> {
const domain = email.split('@')[1];
try {
const mx = await dns.resolveMx(domain);
return mx.length > 0;
} catch {
return false;
}
} Try / catch
try {
await sendMagicLink(email);
} catch (e) {
if (isAffineErrorCode(e, 'invalid_email')) {
show('Your email domain is not verified for this workspace. Use a verified domain.');
} else throw e;
} Prevention
- Verify domain DNS (MX/records) before enabling requireEmailDomainVerification
- Collect allowed domains up front and check the signup form against them
When it happens
Trigger: 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.
Common situations: Self-hosted instances that turned on domain verification; newly purchased domains; internal-only domains without public DNS; verifying from a network with filtered DNS.
Related errors
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/7efb7cd71059529f.
Report an issue: GitHub.
Appendix: 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 b4c8548c09)