Ask ten developers what makes an email address valid and you will get ten regular expressions, most of them wrong in a way that silently discards real customers. The rules are genuinely strange — the specification permits things nobody uses, and forbids things that look completely reasonable — and the practical rules that mailbox providers enforce are narrower still.
This guide covers what the format actually allows, which of those allowances matter when you are extracting or validating addresses in bulk, and where the line sits between “correctly formed” and “a message sent here will arrive”.
An address has two halves and different rules for each
Every address is local-part@domain, split at the last unquoted @. That last-not-first detail matters, because the local part is allowed to contain an @ when quoted, and a parser that splits at the first one will mangle those addresses.
The two halves are governed by different standards and have almost nothing in common. The local part is defined by RFC 5322 and is interpreted only by the receiving mail server — no one else, including you, is entitled to assume anything about its structure. The domain part follows DNS rules and is meaningful to the entire internet. Length limits differ too: 64 octets for the local part, 255 for the domain, and 254 characters for the address as a whole in practice.
The local part: more permissive than you think
Unquoted local parts may contain letters, digits, and this set of punctuation:
! # $ % & ' * + - / = ? ^ _ ` { | } ~ .
Yes, including !, #, %, ? and the backtick. Addresses like john.o'brien@example.com, sales!urgent@example.com and a+b=c@example.com are all well-formed. Apostrophes in particular are not exotic — Irish and Italian surnames produce them constantly, and a validator that rejects them is rejecting real people.
The genuine restrictions on an unquoted local part are narrow:
- A dot may not be first or last:
.dana@example.comanddana.@example.comare invalid. - Two consecutive dots are not allowed:
dana..wright@example.comis invalid. - Spaces, commas, colons, semicolons and angle brackets are not permitted unquoted.
A quoted local part — the whole thing wrapped in double quotes — relaxes nearly all of that. "dana wright"@example.com and "very.unusual.@.unusual.com"@example.com are technically valid. In fifteen years of real lists you will encounter this approximately never, and most sending platforms reject it outright. It is worth knowing the rule exists; it is not worth engineering for.
The domain part: stricter than you think
The domain half is a hostname, and hostnames are conservative: letters, digits and hyphens, split into labels by dots. Each label is at most 63 characters and may not begin or end with a hyphen. Underscores are not valid in a hostname, which surprises people who have seen them in DNS TXT records — those are different record types, not mail domains.
Subdomains are ordinary and increasingly common. dana@mail.corp.example.com is entirely normal in large organisations, and any filter that assumes exactly one dot in the domain will discard it. Large enterprises frequently route mail through regional or departmental subdomains.
Two forms exist that most tools reject deliberately. An IP-literal domain — dana@[192.0.2.1] — is valid per the specification but essentially never legitimate in a contact list. A bare hostname with no dot at all, like dana@localhost, is valid on an internal network and meaningless outside it. Both belong in the discard pile for any list you intend to send to.
Modern TLDs break old assumptions
A great many validators written before 2013 contain a rule like “two to four letters at the end”. That rule was already shaky and is now simply wrong. Since ICANN opened the gTLD programme there are well over a thousand top-level domains, and the assumptions that used to hold do not:
.technology,.internationaland.constructionare far longer than four characters..io,.ai,.coand.meare two, and are now among the most common domains in technology and startup contact lists.- Brand TLDs like
.googleand.bmwexist and carry live mail. - Internationalised TLDs in non-Latin scripts exist, and their ASCII-compatible encoding starts with
xn--.
The practical consequence for anyone cleaning a list: never validate a TLD by length, and be cautious about validating against a hard-coded allowlist unless you intend to maintain it. Exporting the TLD as its own column is a better approach — it lets you eyeball the distribution and spot genuinely suspicious endings without pre-emptively deleting valid contacts.
Plus addressing, dots and subaddressing
Plus addressing (also called subaddressing or tagged addressing) appends a +tag to the local part: dana+conference2026@acme.io. Gmail, Outlook, Fastmail, Proton and most modern providers deliver these to the base mailbox, and people use them to trace who sold their address on. The tag is legitimate, it is part of a valid address, and it usually identifies the same human as the untagged form — which makes it a deduplication question rather than a validation one.
Dots in the local part are provider-specific. Gmail ignores them entirely: d.a.n.a@gmail.com reaches the same inbox as dana@gmail.com. Almost no other provider does this. Applying Gmail’s rule universally will merge two different people at a corporate domain, so the normalisation must be conditional on the domain.
Some organisations also use a hyphen or an equals sign for the same purpose. Because the separator varies, the only rule that generalises is: a tag identifies a mailbox you already have, not a new one.
Internationalised addresses
Two separate standards allow non-ASCII characters, and they apply to different halves of the address.
Internationalised domain names (IDN) let the domain use any script: dana@münchen.de. In DNS this is encoded in Punycode as xn--mnchen-3ya.de. Both forms refer to the same domain, and you will see both in real data depending on whether the source stored the display form or the encoded form.
Internationalised local parts — дана@example.com — are defined by the EAI standards (RFC 6530 and its companions) and require the receiving server to support SMTPUTF8. Support is real but far from universal, and many sending platforms still reject these addresses at import.
For a bulk extraction workflow, the pragmatic position is: match ASCII addresses confidently, expect Punycode domains to pass through as ordinary ASCII, and treat non-ASCII local parts as a case to handle deliberately rather than assume. Normalising to one form before deduplication matters here too — the display form and the Punycode form of the same domain will otherwise be counted as two.
Why every regex is a compromise
A regular expression that implements RFC 5322 completely is famously several thousand characters long, and matching it does not tell you the address works. Every practical matcher therefore chooses a point on a spectrum:
- Too strict and you discard real contacts — apostrophes, plus tags, long TLDs, subdomains. These losses are invisible, which makes them the more dangerous failure.
- Too loose and you import junk: trailing punctuation captured from the surrounding text, version strings, file paths that happen to contain an
@. These are visible and cause bounces.
For extraction specifically, the right trade-off leans slightly loose on the local part and strict on the domain. A malformed local part is usually a real address with a stray character attached, which verification will resolve for a fraction of a cent. A malformed domain is almost never recoverable — there is no mail server to ask.
The other thing extraction must get right is the boundary. In running text, an address is very often followed by a comma, a period or a closing bracket that is not part of it. Deciding where the match ends is a harder problem than deciding whether the middle is well-formed, and it is where most home-grown patterns fail.
Valid is not the same as deliverable
This is the conclusion that matters. Syntax validation answers exactly one question: is this string shaped like an address. It cannot tell you whether the domain resolves, whether it publishes an MX record, whether the mailbox exists, whether it was abandoned three years ago, or whether it is a spam trap placed specifically to catch senders who did not check.
definitely.not.real@thisdomaindoesnotexist.example is a perfectly valid email address. It has a legal local part, a legal domain, a legal TLD. Nothing will ever arrive there.
So treat format checking as the cheap first filter it is — it removes obvious garbage for free — and treat verification as the step that answers the question you actually care about. The order to run them in, and the thresholds to plan against, are covered in how to clean an email list before your first campaign.