Every codebase has one: a regular expression, copied from Stack Overflow, that "validates" email addresses. It feels like a check, but it answers a question almost nobody is actually asking. A regex can tell you a string is shaped like an email address. It cannot tell you the address exists, accepts mail, or won't hard-bounce your next campaign — and those are the only things that matter.
The short answer#
Regex validates syntax, not deliverability. definitely-fake@gmail.com is
a perfectly valid email address by every regex ever written, and it will bounce
the instant you send to it. Worse, the regexes people reach for either reject
real addresses (too strict) or accept nonsense (too loose), and the one that is
technically correct is thousands of characters long and still can't confirm a
mailbox. Use a simple syntax check to catch fat-finger typos at the input, then
verify deliverability with a DNS and SMTP check — which is a network problem, not
a pattern-matching one.
The regex you've seen, and what it lets through#
Here is the archetype — some variant of this lives in most projects:
const re = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
re.test("definitely-fake@gmail.com"); // true ← will hard-bounce
re.test("typo@gmial.com"); // true ← typo'd domain, bounces
re.test("info@company-that-folded.com"); // true ← dead domain
All three pass. All three are undeliverable. The regex did its job perfectly and told you nothing useful, because syntax and deliverability are different questions. Every address a regex can see is a string; whether a human reads mail at it is a fact about the internet, not about the string.
The RFC 5322 rabbit hole#
"Fine," the reasoning goes, "I'll use a correct regex." The formal grammar for
an email address is defined by RFC 5322, and a regex that actually implements it
is famously monstrous — thousands of
characters, and it permits things you would never want to accept, like quoted
local parts with spaces ("a b"@example.com) and comments inside the address.
Two problems follow. First, the strict regex accepts more than you want, not less — it is validating against a 2008 spec, not against "addresses real mail servers will deliver to." Second, even a flawless RFC 5322 match still cannot tell you the domain has a mail server or the mailbox exists. You have spent enormous effort to answer the easy question with more precision, while the hard question — will mail arrive? — remains completely untouched.
The three things regex fundamentally cannot do#
No pattern, however clever, can reach across the network. Regex cannot:
- Check the domain can receive mail.
user@company-that-folded.comis valid syntax on a domain with no MX records. Only a DNS lookup reveals the dead domain. - Confirm the mailbox exists.
noreply-9f2x@gmail.comis valid syntax for an account that was never created. Only an SMTP conversation with Gmail can tell you it isn't there. - Detect a catch-all domain. A catch-all server accepts every address, so even a live SMTP check can't confirm a specific mailbox — and a regex has no idea the domain behaves that way.
These aren't gaps in a particular regex; they are outside what any regex can do, because they are questions about servers, not strings.
What to actually do: validate in layers#
Deliverability is a pipeline of increasingly expensive checks, and syntax is only the cheap first stage (the full picture is in how email verification works):
- Syntax — a simple check at the input to catch obvious typos. This is the only layer regex belongs in.
- Domain and MX — a DNS lookup to confirm the domain can receive mail at all. See the Node.js and Python guides for working code.
- SMTP mailbox probe — the delivery conversation that actually confirms the mailbox, plus catch-all detection. This needs a mail server with a clean IP reputation and careful rate-limiting, which is why most teams reach for a verification API rather than build it.
The syntax check worth keeping#
For layer 1, don't hand-roll RFC 5322. The pragmatic move is the HTML5 email input in the browser (which applies the WHATWG living-standard pattern for free) and a short, permissive check on the server:
// Pragmatic: rejects fat-finger errors, accepts the addresses real
// mail servers actually deliver to. Not a deliverability check.
const SYNTAX = /^[^\s@"]+(?:\.[^\s@"]+)*@[^\s@.]+(?:\.[^\s@.]+)+$/;
SYNTAX.test("jane@example.com"); // true
SYNTAX.test("not-an-email"); // false
SYNTAX.test("a@@b.com"); // false
Use it to give instant feedback at the keyboard — nothing more. Treat a pass as "worth checking properly", never as "valid".
Going the rest of the way#
Once syntax passes, the real verification is a network job. You can build the DNS
and SMTP layers yourself — the language guides above show how far you can get —
but confirming live mailboxes at scale runs into port 25 being blocked on most
hosts, IP reputation, and greylisting, which is
where a managed API earns its place. Qualisend's
POST /verify runs the whole pipeline and returns a four-way
verdict (deliverable | risky | undeliverable | unknown) with a reason code, so
your code acts on whether the mailbox exists rather than whether the string has
an @ in it.
Frequently asked questions#
Is there a correct regex for email validation?#
Not in the sense people want. A regex implementing RFC 5322 exists, but it is
thousands of characters, accepts exotic forms you would never want, and still
can't confirm the address is deliverable. For practical use, a short permissive
pattern (or the HTML5 type="email" input) to catch typos is the right amount of
regex — the rest is a DNS and SMTP problem.
Why does my regex reject valid email addresses?#
Because strict patterns encode assumptions that aren't true — that top-level
domains are 2–3 letters (they aren't: .email, .io, .marketing), that plus
signs or dots aren't allowed in the local part (they are), or that new gTLDs
don't exist. Over-strict regex is a common source of lost signups. Lean
permissive on syntax and verify deliverability separately.
Does HTML5 email validation check if the address is real?#
No. The browser's type="email" validation is a syntax check — a friendlier,
standardized version of the same pattern matching. It catches missing @ signs
and obvious malformations at the input, but it never contacts the mail server, so
it cannot tell you the domain or mailbox exists.
What should I use instead of regex to validate emails?#
Layer it: a permissive syntax check for instant feedback, a DNS/MX lookup to rule out dead domains, and an SMTP mailbox probe to confirm delivery. Build the first two yourself; use a verification API for the SMTP layer, since doing it reliably needs sending-IP reputation and rate-limiting a regex could never provide.
Want to see the difference between "valid syntax" and "will actually deliver"?
The free plan includes 100 verification credits that run the full
pipeline — syntax, DNS, and the SMTP mailbox probe — so you can watch a
regex-approved address come back undeliverable. The
API reference has copy-paste examples in seven languages.