What is email validation?
Email validation is the process of checking whether an email address is correctly formed and able to receive mail before you store it or send to it. The term is often used interchangeably with email verification, which usually means going one step further and confirming that a specific mailbox exists.
Validating addresses at the point of entry pays off quickly:
- Fewer bounces. High bounce rates damage your sender reputation with Gmail, Outlook and other providers, so even legitimate mail starts landing in spam.
- Recovered sign-ups. A user who types
gmial.comnever receives your welcome email. Catching the typo while they're still on the form saves the account. - Less abuse. Throwaway inboxes are a common tool for free-trial abuse, promo farming and fake accounts.
- Cleaner data. Sales and support teams waste time on leads that can never be reached.
A thorough check works through the layers below, from cheapest to most expensive.
1. Check the syntax
An address has two parts separated by the last @: the local part (before) and the domain (after). The rules come from RFC 5321 and RFC 5322:
- The whole address can be at most 254 characters, and the local part at most 64.
- The local part may contain letters, digits and
! # $ % & ' * + / = ? ^ _ ` { | } ~ -, plus dots. A dot can't come first or last, and you can't have two in a row. - The domain is a series of labels separated by dots. Each label is 1–63 characters of letters, digits and hyphens, and can't start or end with a hyphen. The top-level domain can't be all digits.
- Internationalised domains (
user@münchen.de) are valid and are converted to punycode (xn--mnchen-3ya.de) for DNS lookups.
Why a regex isn't enough
The standards technically allow quoted local parts ("john doe"@example.com), comments and IP-address domains (user@[192.0.2.1]). A regex that accepts all of that is unreadable, and one that is simple enough to maintain either rejects real addresses or accepts broken ones. For example, this common pattern is a reasonable first filter in the browser:
// Good enough to catch obvious mistakes – not a real validator.
const looksLikeEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input);It still accepts a..b@example.com and user@-example.com, and it can't tell you anything about whether the domain exists. Use syntax checks to reject obvious garbage quickly, then move on to the checks that need the network. In practice, quoted local parts and IP-literal domains almost never appear in legitimate sign-ups, so most validators, including ours, treat them as invalid.
2. Check that the domain exists
A perfectly formed address on a domain that doesn't exist can never receive mail. A DNS lookup answers this in milliseconds: if the resolver returns NXDOMAIN, the domain isn't registered (or has lapsed), and the address is invalid.
Be careful to distinguish "doesn't exist" from "couldn't check". A timeout or SERVFAIL is a temporary failure, so treat the result as unknown and retry later rather than rejecting a real user.
3. Check for mail servers (MX records)
A domain that exists may still not accept email. Mail is routed using the domain's MX records, each of which names a mail server and a priority (lower is tried first):
gmail.com. MX 5 gmail-smtp-in.l.google.com.
gmail.com. MX 10 alt1.gmail-smtp-in.l.google.com.Two edge cases matter:
- Null MX (RFC 7505). A single MX record of
0 .is the domain owner explicitly saying "this domain accepts no mail". Addresses there are invalid. - Implicit MX. If there are no MX records at all, SMTP falls back to the domain's A/AAAA record. Mail can technically be delivered, but real mailbox providers almost always publish MX records, so this is a risk signal.
4. Detect disposable inboxes
Disposable (temporary or "burner") email services such as Mailinator, Guerrilla Mail and 10 Minute Mail hand out inboxes that work for a few minutes or hours. The addresses are syntactically valid and their domains have working MX records, so only a list-based check catches them.
Thousands of these domains exist and new ones appear constantly, so the list needs regular updates. Also match subdomains: anything.mailinator.com is just as disposable as mailinator.com. See our disposable email checker for more on how this works.
5. Flag role-based addresses
Addresses like info@, support@, sales@ and noreply@ usually reach a shared inbox or nobody at all. They're valid, but for marketing email they tend to have low engagement and higher complaint rates, and many email service providers discourage sending to them.
Whether to accept them depends on context: a B2B contact form may be happy with sales@company.com, while a consumer newsletter probably isn't. Flag them and let your own policy decide.
6. Catch typos and suggest a fix
A large share of bad addresses are simple typos of popular providers: gmial.com, hotmial.com, yahooo.com, gmail.con. Comparing the domain against well-known providers with an edit-distance algorithm (such as Damerau–Levenshtein, which counts a swapped pair of letters as one edit) catches most of them.
Some typo domains are registered by third parties and even accept mail, so a typo can pass every other check. The fix is to show the suggestion to the user ("Did you mean jane@gmail.com?") rather than silently correcting it.
7. Mailbox verification (SMTP)
The final layer asks the recipient's mail server about the specific mailbox. A verifier connects to the MX host on port 25 and starts an SMTP conversation, then stops before sending anything:
HELO verifier.example
MAIL FROM:<check@verifier.example>
RCPT TO:<jane@company.com> ← 250 = accepted, 550 = no such user
QUITIt's powerful but imperfect:
- Catch-all domains accept every address, so a
250doesn't prove the mailbox exists. - Greylisting and rate limits produce temporary failures that look like rejections.
- Major providers increasingly accept all recipients at this stage, or block verification attempts from unknown IPs.
- It needs a dedicated server with a clean IP address and proper reverse DNS, because many cloud platforms block outbound port 25.
checks.smtp field for it.Email validation in practice
- Validate on the server. Client-side checks are good for instant feedback, but they can be bypassed, and an API key in browser code can be stolen.
- Validate at the point of entry. It's far cheaper to fix an address while the user is still on the form than to clean your list later.
- Block invalid, decide on risky. Reject addresses that can't receive mail. For disposable, role-based and typo-suspect addresses, choose a policy per form.
- Don't punish "unknown". A temporary DNS failure isn't the user's fault. Accept the address and re-check it later.
- Re-validate old lists. Domains expire and companies shut down. A list that was clean a year ago won't be today.
- Keep double opt-in where it matters. Validation tells you an address can receive mail. A confirmation email proves the person typing it actually owns it.
Doing it with an email validation API
Building it yourself in Node.js? Our step-by-step Node.js email validation guide walks through every check with tested code. Building and maintaining all of this yourself means DNS handling, an always-current disposable list and a typo dictionary. An email validation API does it in one request:
const res = await fetch(
"https://validateemail.io/v1/validate?email=" + encodeURIComponent(email),
{ headers: { Authorization: `Bearer ${process.env.VALIDATEEMAIL_KEY}` } }
);
const { status, reason, did_you_mean } = await res.json();
if (status === "invalid") rejectSignup(did_you_mean);
else if (reason === "disposable") rejectSignup(null, "Please use a permanent email address");
else createAccount(email);Every response includes an overall status (valid, invalid, risky or unknown), a machine-readable reason, a confidence score and the result of each individual check. See the API reference for every field.