Gmail does tell you if an address exists. I measured 39 domains.
“You cannot verify a Gmail address, Google accepts mail for anything” is repeated everywhere and is false at RCPT TO. The domains you genuinely cannot verify are the B2B ones — including google.com itself.
Every guide to email verification repeats the same line: the big consumer providers accept mail for addresses that do not exist, so a per-mailbox answer from them is guesswork. I was about to write that line into our own documentation. Instead I measured it, because we were about to make product decisions on the back of it.
It is false. And the truth is close to the exact inverse of the received wisdom.
The measurement
Thirty-nine domains, a real SMTP conversation against each domain’s live MX — connect, EHLO, MAIL FROM, RCPT TO for a real address, then RCPT TO for a random local part at the same domain to detect a catch-all. No mail is ever sent; a probe never reaches DATA. First run on 4 August 2026, then repeated on 22 August from a different host, because a single vantage point measures your own IP’s reputation as much as it measures anyone else.
discriminates 17/39 44% a probe can verify addresses here catch-all 11/39 28% unverifiable by anyone, at any price no answer 10/39 26% see below — this row is about the asker no MX 1/39 3%
Both runs agreed in every particular.
Consumer mailboxes answer honestly
Gmail discriminates perfectly. A real address gets a 250; an invented one gets a 550.
a.real.mailbox@gmail.com 250 2.1.5 OK definitely-not-real-zzq9174@gmail.com 550-5.1.1 does not exist
So do iCloud, Proton, Yandex, Naver, Rediffmail and Zoho — all of which sit on the usual do-not-bother lists. Our own list of “providers that will not give a reliable answer” excluded providers that answer perfectly well, which is the kind of error that only shows up when you stop copying and start dialling.
The domains you cannot verify are the B2B ones
google.com is a catch-all. It accepts mail for addresses that do not exist:
sundar@google.com 250 2.1.5 OK hiradhram.jhaojha@google.com 250 2.1.5 OK <- catch-all
So are github.com, stripe.com, vercel.com, cloudflare.com, shopify.com, atlassian.com and zoom.us. Eleven of thirty-nine. A catch-all domain is unverifiable by anyone, at any price, forever — no amount of infrastructure changes what the server will say. If a vendor hands you a confident yes or no on a github.com address, they made it up.
Which inverts the usual advice. Consumer signups are largely verifiable. Signups from tech companies largely are not. If you are selling B2B SaaS, mailbox verification is close to useless on exactly the addresses you care about, and nobody selling it to you says so.
The third row is about me, not about Microsoft
Ten domains refused to answer, and the useful part is that they said why:
outlook.com / hotmail.com / live.com 550 5.7.1 Service unavailable, Client host [<residential IP>] yahoo.com / aol.com 550 5.7.25 Forward-confirmed reverse DNS failed gmx.com / web.de / mail.com 554 see postmaster.<domain> amazon.com 554 SBRS score too low
Not one of those is a statement about the domain. They are rejections of the asking host — a residential line with no reverse DNS and no sending reputation. A probe box with proper rDNS would very likely get real answers from most of them. Read that row as a ceiling on what a bad vantage point can see, never as a property of Microsoft or Yahoo. It is also the reason to publish the method with the numbers: a measurement you cannot reproduce from your own host is an anecdote.
The bug this nearly shipped
Our probe sends two RCPT TO commands: the real address, then a random one to test for a catch-all. Deferring the second and later RCPT in a session is standard anti-directory-harvesting behaviour, so a careful mail server answers the first and stalls the second — which is precisely the case we walk into by design.
The inference read, in effect, that accepting the real address was evidence the domain discriminates. It is evidence of nothing: a server that accepts everything also accepts the real one. Only the fate of an address nobody has is informative. So a 250 on the real address plus a deferral on the catch-all probe returned mailbox_exists: true — a definite yes built on a question the server had declined to answer.
That is the expensive direction. A false “this mailbox is real” is a fraudulent signup let through on our say-so. It now returns null unless the catch-all question was actually answered. A rejection still survives an unknown, deliberately: a 550 means the mailbox is not there whatever the catch-all status, because a domain that accepts everything does not answer 550.
The same session found a second one: a server that hangs up mid-conversation left the probe waiting forever, because once a socket closes Node clears its own inactivity timer and neither the timeout nor the error handler fires. Both were found by pointing the real worker at a mail server we could script, which was impossible until then — the SMTP port was hardcoded, binding port 25 needs root, and outbound 25 is blocked from every machine we develop on.
What we actually do today
We do not run this probe in production. It needs a host that permits outbound port 25, our API runs somewhere that blocks it outright, and renting a box for a signal that cannot answer for 28% of domains is not yet worth it. So mailbox_exists is null on every address we return, and the response says which kind of unknown it is rather than leaving you to guess: the domain accepts everything, the server declined, or we never got there.
Stating that is the point. The reason this survey exists is that we were about to inherit a claim from other people’s documentation without checking it, and the claim was wrong in both directions — excluding providers that answer honestly, admitting domains that cannot answer at all. The cheapest way to be wrong about fraud is to repeat what everyone knows.