Skip to content

Developers · 6 min read

Email Address Validation Test Cases: Edge Cases Forms Get Wrong

Email address validation test cases for your form: valid and invalid formats, plus addressing, unicode, IDN domains, lengths and normalization.

Aug 18, 2026 · SimpleCold team

A test table of email inputs with expected accept or reject results, such as jane@@example.com rejected for two at signs

Most email validation bugs are found by customers. Someone with an apostrophe in their surname can't sign up, someone with a +tag address gets told it's invalid, or a pasted address with a trailing space quietly fails. A good set of email address validation test cases catches these before release.

Below is the set we'd put in any test suite for a signup or contact form, grouped by what each group tests. Copy the tables into your fixtures and adjust the expected column to your own policy.

How to read the tables

There are three possible outcomes for each case:

  • Accept: a well-built form should let it through.
  • Reject: the format is wrong, or so unusual in practice that rejecting it is the sensible policy.
  • Policy: valid by the RFCs but rare; decide once and document it.

Format tests only tell you whether a string is shaped like an address. The last section covers the cases where format is fine and the address still won't work.

Ordinary addresses that must pass

InputExpectedWhy it's here
[email protected]AcceptBaseline
[email protected]AcceptDot in local part
[email protected]AcceptUnderscore
[email protected]AcceptHyphen
[email protected]AcceptOne-character local part
[email protected]AcceptDigits
[email protected]AcceptAll-digit local part
[email protected]AcceptUppercase (normalize the domain afterwards)
[email protected]AcceptSubdomain and multi-part TLD
[email protected]AcceptLong TLD
[email protected]AcceptHyphen inside a domain label
[email protected]AcceptDomain label starting with a digit

Characters real people use

These are the ones overly strict patterns reject.

InputExpectedWhy it's here
[email protected]AcceptPlus addressing, supported by Gmail and many others
[email protected]AcceptEmpty tag after the plus
o'[email protected]AcceptApostrophe
jane%[email protected]AcceptPercent sign, legal and occasionally used
jane&[email protected]PolicyLegal; some downstream tools mishandle it
[email protected]PolicyLegal, rare
jane/[email protected]PolicyLegal, rare
[email protected]PolicyLegal, rare

Whitespace and copy-paste junk

Trim before validating, then check the trimmed value.

InputExpectedWhy it's here
␠[email protected] (leading space)Accept after trimCopy-paste
[email protected]␠ (trailing space)Accept after trimCopy-paste
[email protected] followed by a non-breaking spaceAccept after trimSpreadsheets and rich text editors
jane @example.comRejectSpace inside
jane@exam ple.comRejectSpace in domain
[email protected].PolicyTrailing dot; usually a typo, reject or strip
mailto:[email protected]Reject, or strip the prefixPasted from a link
Jane Doe followed by the address in angle bracketsReject, or extractPasted from an email client

Make sure your trim handles unicode whitespace, not only the ASCII space. In JavaScript, String.prototype.trim() does; in some other languages you need to be explicit.

Structural errors that must fail

InputExpectedWhy it's here
janeexample.comRejectNo @
jane@@example.comRejectTwo @
jane@[email protected]Reject@ in domain
@example.comRejectEmpty local part
jane@RejectEmpty domain
jane@exampleRejectNo dot in domain (a dotless host is legal but not useful for public forms)
[email protected]RejectLeading dot in local part
[email protected]RejectTrailing dot in local part
[email protected]RejectConsecutive dots
[email protected]RejectDomain starts with a dot
[email protected]RejectEmpty domain label
[email protected]RejectLabel starts with a hyphen
[email protected]RejectLabel ends with a hyphen
[email protected]PolicyOne-letter TLD; none exist today
jane,[email protected]RejectComma
jane;[email protected]RejectSemicolon (also a common list separator)

Lengths

InputExpectedWhy it's here
Local part of exactly 64 charactersAcceptUpper limit
Local part of 65 charactersRejectOver the 64-octet limit
Whole address of 254 charactersAcceptPractical upper limit
Whole address of 255 charactersRejectOver the limit
Domain label of 63 charactersAcceptDNS label limit
Domain label of 64 charactersRejectOver the DNS label limit

Generate these in code rather than typing them, so the length is exact.

Unusual but RFC-valid forms

The RFCs allow forms that almost nobody uses in practice. Decide your policy once. For consumer and B2B forms, rejecting them is normal and saves your CRM and ESP from strings they may not handle.

InputExpectedNotes
"jane doe"@example.comPolicy (usually reject)Quoted local part with a space
"jane@home"@example.comPolicy (usually reject)Quoted @
jane@[192.0.2.1]Policy (usually reject)IP-literal domain
jane@[IPv6:2001:db8::1]Policy (usually reject)IPv6 literal
jane(comment)@example.comPolicy (usually reject)Comments are allowed by RFC 5322

Internationalized addresses

InputExpectedNotes
jane@bücher.deAcceptInternationalized domain name; convert to punycode (xn--bcher-kva.de) for DNS lookups
[email protected]AcceptPunycode form of the same domain
josé@example.comPolicyUnicode local part (SMTPUTF8); not every mail system supports it
用户@例子.广告PolicyFully internationalized address
jane@exаmple.com with a Cyrillic "а"Reject or flagMixed-script lookalike, a spoofing risk

If you accept unicode, store addresses in a normalized form (NFC) so the same address doesn't end up in your database twice.

Normalization and duplicates

Not strictly validation, but they belong in the same test file.

InputsExpectedNotes
[email protected] and [email protected]Same domain after normalizationDomains are case-insensitive
[email protected] and [email protected]PolicyLocal parts are technically case-sensitive; almost every provider treats them as the same
[email protected] and [email protected]PolicyGmail ignores dots in consumer local parts; other providers don't
[email protected] and [email protected]PolicySame Gmail inbox; removing tags breaks users who rely on them

Be careful with provider-specific rules. Stripping dots is correct for consumer Gmail and wrong for most other domains.

Cases format checks can't settle

Every address in this table has perfect syntax. A format check accepts all of them. They still fail or need care:

InputWhat's actually wrong
[email protected]Likely typo of a webmail domain
[email protected]Reserved TLD that never resolves
[email protected]Domain exists but has no mail server
[email protected]Mailbox doesn't exist
[email protected]Disposable address service
[email protected]Role-based address
[email protected]Domain accepts every address; can't be confirmed

These are the job of DNS lookups and mailbox verification. For integration tests against the SimpleCold API, use the free test addresses ([email protected] for deliverable, [email protected] for a missing mailbox, [email protected] for catch-all, [email protected] for disposable, and so on). They return fixed results and don't use credits on single and batch calls. The test emails guide lists them all.

Wiring it into your suite

  • Store the tables as fixtures (JSON or CSV) with input, expected and note columns.
  • Run them against both your client-side and server-side validators.
  • Add a case each time a customer reports a false rejection.
  • Run DNS and verification cases separately from unit tests, since they depend on the network.

For the patterns themselves, see email validation regex, and for a quick manual check of any single address, the email syntax checker.

Check your list before you send it

Start with 200 free credits. Pay per credit after that.