Email Validator

Growth and marketing teams run an exported list through this before a send, developers validate signup input before a row is written, and support staff paste an address here when a bounce comes back as 550 5.1.1 address rejected. The checks are layered: RFC shape rules first, then heuristics for disposable domains, role accounts, and provider typos, then an optional live MX query. Everything runs in your browser, and the only network traffic is the DNS request you start with the MX button.

Preset examples
Checks run locally as you type.
Result Invalid
Address —
Local part —
Domain —
Sends only the domain to Cloudflare DNS-over-HTTPS. No mail is sent.

Bulk list audit

Paste addresses separated by commas, semicolons, spaces, or new lines. Counts and the table update as you type.

0
Total
0
Valid
0
Invalid
0
Duplicates
0
Role
0
Disposable
0
Typo
Address Status Notes

How the Tool Checks an Address

The first pass is pure shape. Input is trimmed, a display name inside angle brackets is pulled out, and stray whitespace is removed before the string is split at the @ sign. The local part is held to the 64-character limit and checked for dot placement, consecutive dots, and characters outside the RFC 5321 set. A quoted local part is accepted when the quotes wrap the whole local part and end right before the @, which is the RFC form for a value containing an @ sign; whitespace is stripped before parsing here, so a space inside the quotes does not survive. The domain is held to 253 characters, split into labels of at most 63 characters, and rejected when a label starts or ends with a hyphen, when two dots sit next to each other, or when the top-level domain is all digits. The full address is capped at 254 characters, and a bracketed IP literal like user@[127.0.0.1] passes with a warning because public providers rarely accept it.

Shape says nothing about whether a mailbox exists, so the second pass works on the parsed pieces. The domain is matched against a built-in list of throwaway providers and flagged as disposable when it hits. Edit distance against common providers turns gmai.com into a one-click fix, and a .con ending is corrected to .com. Role local parts such as support, sales, and noreply are flagged because they read a shared inbox, and Gmail addresses get a note about dots being ignored and plus tags collapsing into one mailbox. The third pass is live: pressing Check MX queries DNS-over-HTTPS for the domain and falls back to the A record when no MX record exists, which RFC 5321 treats as implicit mail routing.

Shape rules that catch real typos

Two dots in a row inside the domain, a label that begins with a hyphen, and a top-level domain made only of digits are the three failures loose patterns miss most often. The digit rule matters because user@192.168.1.5 looks reasonable to a hand-written pattern while the RFC requires the bracket form user@[192.168.1.5]. A trailing dot and an empty label are rejected at the same stage, before any DNS query is made.

Reading errors, warnings, and suggestions

An error means the address fails shape rules and should not be stored as typed. A warning means it will probably work but deserves a look before you send: a disposable domain, a shared inbox, a Gmail address that duplicates another row, or a domain one or two edits from a common provider. The suggestion row is the only one carrying a button, and Apply rewrites the domain in place. The checks themselves make no network requests.

Before and after: a pattern that lets broken addresses through

Before (all three inputs pass)
const naive = /^[\w.]+@[\w.]+$/;
naive.test("a@b..com");               // true, b..com has an empty label
naive.test("john.smith@example.com"); // true, no length or hyphen rules

const looser = /^[^@]+@[^@]+$/;
looser.test("john smith@example.com"); // true, a space in the local part passes
After (layered checks report each case)
validateEmail("a@b..com");
// valid: false
// errors: ["Domain cannot contain two consecutive dots."]

validateEmail("john smith@example.com");
// valid: true once the space is removed
// address: "johnsmith@example.com"
// warnings: ["Whitespace was removed from the address before validation."]

validateEmail("john.smith@example.com");
// valid: true, no warnings (a dot in the local part is legal)

Use Cases

Team Situation What to look at
Marketing ops A 40,000-row export lands the day before a campaign send Duplicate count, disposable flags, role addresses, typo suggestions
Developer A signup form is about to write the address into the users table Errors block the request; one MX check runs before the confirmation mail
Support Replies to a customer address bounce with 550 5.1.1 address rejected Role address, MX records, and a domain one edit from a real provider

Common Mistakes

  • Treating a regular expression as complete validation. A loose pattern accepts a@b..com and never checks label length, hyphen placement, or the top-level domain.
  • Rejecting plus-addresses as malformed. john.doe+news@gmail.com is a normal address, and the plus is a routing tag that major providers deliver to the base mailbox.
  • Assuming syntax means the mail will arrive. user@example.con passes every shape rule and is only flagged as a likely typo, so press Check MX before mailing a domain you have never used.
  • Treating the disposable list as a wall. New throwaway domains keep appearing, so read the flag as a reason to review the address and pair it with an MX check.
  • Deleting role addresses everywhere. support@ and billing@ should still receive receipts and password resets; drop them from marketing sends only.
  • Reading only the valid count from a bulk audit. Duplicates and typo suggestions are where the losses hide, and a list can be 100% valid while two rows point at the same mailbox.

Best Practices

  • Validate in the browser for instant feedback and repeat the same checks on the server before writing the row. Client-side checks alone are easy to bypass.
  • Run the MX query at signup rather than on every keystroke. One DNS-over-HTTPS request per new address is enough and keeps the form quick.
  • Keep the raw input next to the normalized address. Storing " contact@example.com " exactly as typed lets you re-run checks when the rules change, and it records what the user submitted.
  • Re-run the audit before every send instead of once a quarter. Disposable and role addresses accumulate, so a list cleaned in March carries junk in June.
  • Strip display names during import. A line like Contact <contact@example.com> is a single address, and counting the display name as part of the address creates false duplicates.
  • Record the bounce code beside the validation result. A 550 5.1.1 on an address that passed shape checks tells you the receiving server disagreed, which is what the MX check and the typo review are for.

Frequently Asked Questions

Is this a complete RFC 5322 validator?

It is practical RFC 5321 shape checking plus the RFC 5322 cases people actually type. The local part is checked for dot placement, consecutive dots, the allowed character set, and quoted strings, while the domain is checked for label length, hyphen placement, and a sensible top-level domain. The awkward corners of RFC 5322, such as folding whitespace, comments in parentheses, and obsolete obs- forms, are left out here, because Gmail, Outlook, and every bulk sender rejects those addresses anyway. A passing result means the address is well formed, not that it matches every grammar production in the document.

Does a valid result mean the mail will arrive?

No. Syntax only says the address is shaped correctly, and delivery depends on the receiving server as well. A catch-all domain accepts everything, a full mailbox returns a 552 after acceptance, and greylisting makes the first attempt bounce with a temporary 4xx code. The MX button, the typo suggestion, and the disposable flag cover the failure modes you can see before sending. Treat a green result as allowed to try, not as a promise of delivery.

What does the Check MX button query?

It sends one DNS-over-HTTPS request to cloudflare-dns.com for the domain’s MX records, then falls back to an A record query when no MX record exists. Only the domain crosses the network: the local part and the full address stay in the browser, and no mail is ever sent. Nothing runs on page load or while you type; the request happens only when you press the button. A reply of NXDOMAIN means the domain does not exist in DNS at all.

Why did a plus-address trigger a note?

Gmail and Google Workspace treat everything after a plus sign as a routing tag, so john.doe+newsletter@gmail.com lands in the same mailbox as johndoe@gmail.com. Gmail also ignores dots in the local part, which means john.doe and johndoe are one inbox rather than two. The note tells you that several rows in a list may collapse to a single mailbox, which inflates counts and draws provider throttling. The address itself is valid; the note is about list hygiene.

Why do you warn about role addresses?

Addresses such as support@, sales@, info@, and noreply@ point at a shared inbox instead of one person. Nobody there remembers subscribing, so opens are low, and when someone finally complains it costs more sender reputation than a complaint from a regular inactive contact. The usual handling is to keep role addresses out of signup forms and off marketing sends while still letting receipts and password resets through.

Are my addresses stored or sent anywhere?

Validation runs in your browser’s memory. The single-address check and the bulk audit make no network request, so typing into either field only calls local functions. The only traffic this page produces is the DNS-over-HTTPS lookup you start with the Check MX button, and that request carries the domain name only. Closing the tab discards everything.

How do I fix a flagged domain typo?

Press Apply next to the suggestion to rewrite the domain in one step, or edit the address by hand when the suggestion is wrong. Suggestions come from edit distance against a list of common providers, so gmai.com maps to gmail.com and hotmial.com maps to hotmail.com. Matches up to two edits are accepted, and the comparison is skipped for domains shorter than six characters to keep out nonsense results. When nothing appears, the domain is either correct or the mistake is larger than the search looks for.