How email verification actually works, step by step

What really happens between “submit” and a verdict — syntax, DNS, the live SMTP conversation, and why some addresses can never be known for sure.

The problem in one sentence

An email address that looks perfect can still be undeliverable. [email protected] is valid syntax, on a real domain, with working mail servers — and may still bounce because the mailbox jane was never created or was deleted last year. Verification exists to answer one question before you hit send: will the receiving server actually accept mail for this address?

Getting that answer means walking a chain of checks, cheapest first, bailing out as soon as a step is decisive. Here is the whole chain.

Step 1 — Syntax and normalization

First we parse the address into its local part and domain and check it against the rules that actually matter in practice (not the full, almost-never-used RFC 5322 grammar). Empty local part, missing @, illegal characters, a domain with no dot, a trailing dot — all rejected here for free, before any network call.

We also normalize: l/owercase the domain, trim stray whitespace, and run a typo check against common providers. A signup that reads [email protected] almost certainly meant gmail.com, and surfacing a did-you-mean suggestion recovers a real customer instead of silently losing them.

Step 2 — DNS and MX records

A domain can resolve and still not accept email. What we need is its MX (Mail eXchanger) records — the DNS entries that say “send mail for this domain to these servers.” We look them up over DNS-over-HTTPS for speed and reliability.

No MX records (and no usable A-record fallback) is a decisive answer: nothing can receive mail there, so every address at that domain is undeliverable. If MX records exist, we now know where to ask the next question.

Step 3 — The live SMTP conversation

This is where verification earns its keep. We open a connection to the highest-priority mail server and begin an ordinary SMTP handshake — the same one any mail server would — but we stop short of actually sending anything:

220 mx.acme.com ESMTP ready
> EHLO verify.mailbounce.co
250 mx.acme.com
> MAIL FROM:<[email protected]>
250 OK
> RCPT TO:<[email protected]>
250 OK            ← the server will accept mail for jane
> QUIT

That RCPT TO response is the signal. A 250 means the server is willing to accept mail for the mailbox; a 550 ("no such user") means it is not. Crucially, we never send the DATA — no message is ever delivered to the person. We ask the question and hang up.

Doing this politely matters: a real HELO name, a reachable return address, correct PTR/SPF on the sending IP, and sane rate limits. Servers that suspect abuse will simply lie to you, which brings us to the hard part.

Step 4 — When the server won't give a straight answer

Two common situations make a clean verdict impossible, and pretending otherwise is how verifiers lose your trust:

Catch-all (accept-all) domains. Some servers answer 250 OK to every RCPT TO, whether or not the mailbox exists, so that no legitimate mail is ever lost to a typo. On a catch-all domain, the SMTP layer literally cannot tell you whether jane@ is real — the only way to know would be to send a message and watch for a later bounce.

Greylisting and rate limits. Other servers temporarily defer unknown senders (a 4xx "try again later"), or throttle probes to fight abuse. A deferral isn't a yes or a no; it's "ask again in a few minutes."

An honest verifier returns catch-all or unknown in these cases instead of guessing. A fabricated "valid" here is worse than useless — it's the result you'll trust right up until it bounces.

Putting it together: the verdict

Stacking the steps gives a small, honest set of outcomes:

  • Valid — syntax good, MX present, mailbox accepted at RCPT TO.
  • Invalid — bad syntax, no MX, or the mailbox was explicitly rejected.
  • Catch-all — the domain accepts everything; deliverable but unconfirmable.
  • Unknown — greylisted, timed out, or otherwise inconclusive.
  • Plus orthogonal flags: disposable, role (info@, sales@), and free-provider.

That last distinction — separating "we couldn't tell" from "it's bad" — is the whole game. It's also why we don't bill for unknown results: you shouldn't pay for an answer the protocol refused to give.

How MailBounce does it

MailBounce runs exactly this pipeline — syntax, typo suggestions, DNS/MX over DoH, disposable/role/free detection, and a real RCPT TO probe from a dedicated mail server — and returns it as clean JSON. You can watch the whole chain run on any address, free and with no credit, in the playground, or wire it into your signup form with the real-time API.

Frequently asked questions

Does verifying an address send the person an email?

No. We stop the SMTP conversation at RCPT TO — before the message body (DATA) is ever transmitted. The recipient never receives anything.

Why can't you confirm catch-all addresses?

A catch-all domain accepts mail for every address by design, so the server returns the same 250 OK whether or not a mailbox exists. No verifier can confirm a specific mailbox without actually sending a message and watching for a bounce.

References

T

The MailBounce Team

Engineering · MailBounce builds a developer-first email-verification API.

Verify your list before your next send

Run the full pipeline free in the playground — no credit card, no credits spent.

Start free