nextauthjs/next-auth · warning
Invalid email address format.
Error message
Invalid email address format.
What it means
defaultNormalizer normalizes the submitted email with NFKC, lowercases and trims it, then applies sanity checks. Emails containing double quotes are rejected outright to prevent parser-confusion attacks such as "attacker@evil.com"@victim.com, producing 'Invalid email address format.'
Source
Thrown at packages/core/src/lib/actions/signin/send-token.ts:108
})}`,
}
}
export function defaultNormalizer(email?: string) {
if (!email) throw new Error("Missing email from request body.")
// Apply Unicode NFKC normalization *before* validation. Without this, a
// character that is a homoglyph of `@` (e.g. U+FF20 FULLWIDTH COMMERCIAL AT)
// passes the single-`@` check below, but can later be canonicalized to an
// ASCII `@` by a downstream address parser, splitting the address into
// multiple recipients. Normalizing first ensures any such homoglyph is
// turned into a real `@` and rejected by the checks below.
const trimmedEmail = email.normalize("NFKC").toLowerCase().trim()
// Reject email addresses with quotes to prevent address parser confusion
// This prevents attacks like "attacker@evil.com"@victim.com
if (trimmedEmail.includes('"')) {
throw new Error("Invalid email address format.")
}
// Get the first two elements only,
// separated by `@` from user input.
let [local, domain] = trimmedEmail.split("@")
// Validate that we have exactly 2 parts (local and domain)
if (!local || !domain || trimmedEmail.split("@").length !== 2) {
throw new Error("Invalid email address format.")
}
// The part before "@" can contain a ","
// but we remove it on the domain part
domain = domain.split(",")[0]
// Additional validation: domain should not be empty after comma split
if (!domain) {
throw new Error("Invalid email address format.")View on GitHub (pinned to a1a16a5a77)
Solutions
- Strip quotes from user input before submitting, or show a validation error telling the user the address contains invalid characters
- Use type="email" and a client-side regex that disallows quotes to catch it before the request
- If legitimate quoted local-parts must be supported, pre-normalize on your side or use a custom normalizer before calling the provider's send flow
Example fix
// before
const email = rawInput; // "bob"@example.com
// after
const email = rawInput.replace(/"/g, '').trim();
if (!/^[^@\s"]+@[^@\s"]+$/.test(email)) throw new Error('Invalid email'); Defensive patterns
Strategy: validation
Validate before calling
if (/^[^@\s"]+@[^@\s"]+$/.test(email) && !email.includes('"')) {
await signIn('email', { email });
} Type guard
function isQuoteFreeEmail(v: string): boolean {
return !v.includes('"') && /^[^@]+@[^@]+$/.test(v);
} Try / catch
try {
await signIn('email', { email });
} catch (e) {
if (/Invalid email address format/.test(String(e))) {
// show 'please enter a valid email address' and sanitize quotes
}
} Prevention
- Sanitize pasted input: strip quotes and display-name decorations before submit
- Use type="email" inputs to leverage browser validation
- Never accept RFC 5322 quoted local parts in user-facing forms
- Add a regex check rejecting quotes, spaces, and multiple @ before calling signIn
When it happens
Trigger: Submitting an email that contains a double-quote character anywhere in the string — the check `trimmedEmail.includes('"')` rejects it before further validation.
Common situations: Users pasting quoted addresses copied from mail clients (display names with quotes); stored addresses in legacy systems using RFC 5322 quoted local parts; test inputs with quotes; injection attempts being correctly rejected.
Related errors
- Missing email from request body.
- malformed Mailgun domain
- No user id.
- User id is required
- credential id is required
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/0a3df24aaf508d41.
Report an issue: GitHub.