RFC 5322 Deep Dive
What RFC 5322 Actually Says
RFC 5322 (Internet Message Format) defines the format of email messages including the structure of email addresses. It is often cited but rarely read. The result is validators that implement a popular myth of what email addresses look like, rather than what the standard actually permits.
The address format you probably know: localpart@domain. What you may not know is how flexible each part can be.
The Local Part
The local part (everything before the @) can take two forms: a dot-atom or a quoted string.
Dot-atom form: A sequence of "atext" characters, separated by dots, where no dot appears at the start or end and no two dots appear consecutively.
The "atext" characters are: letters (A-Z, a-z), digits (0-9), and these symbols:
! # $ % & ' * + - / = ? ^ _ ` { | } ~
This is broader than most people expect. All of the following are valid local parts under RFC 5322:
user+tag(the+is valid)user_name(the_is valid)user!name(the!is valid)user#tag(the#is valid)very.common(dots between atext sequences are valid)disposable.style.email.with+symbol(multiple dots and a+)
Quoted string form: The local part may be enclosed in double quotes, allowing a broader set of characters including spaces:
"user name"@example.com— valid per RFC 5322"user@example"@example.com— valid (the@inside quotes is literal)"very.unusual.\"@\".unusual.com"@example.com— valid
Most email validators do not support quoted strings. This is technically a bug — they reject valid email addresses — but it is so universal in practice that major mail systems don't use quoted local parts either.
What Is NOT Valid in the Local Part
The dot rules are strict:
- Cannot start with a dot:
.user@example.com— invalid - Cannot end with a dot:
user.@example.com— invalid - Cannot have two consecutive dots:
user..name@example.com— invalid
The following characters are NOT valid in the unquoted local part (they require quoting):
( ) [ ] \ , ; : < > @
Spaces are also not valid without quoting.
Common Validator Bugs
Real-world validators frequently get these wrong:
Bug: Rejecting + in local part
This is the most common validator bug. The + character is explicitly valid in the dot-atom form. Gmail uses it for address tagging (user+newsletter@gmail.com). Any validator that rejects it is non-conformant and will block real Gmail users.
Bug: Rejecting consecutive subdomains in domain
user@mail.example.co.uk is valid. Some validators reject domains with more than one dot, treating only @example.com form as valid.
Bug: Rejecting quoted strings
"user name"@example.com is valid per RFC 5322. Validators that reject anything with spaces or that require the local part to match [a-zA-Z0-9._%+-]+ will reject this.
Bug: Maximum length not at the right granularity
RFC 5321 (the SMTP protocol) specifies: local part MUST NOT exceed 64 characters; the entire address MUST NOT exceed 320 characters; domain labels must not exceed 63 characters. Most validators either don't enforce these or enforce them with off-by-one errors.
Bug: Case-normalizing the local part
The RFC is explicit that the local part is technically case-sensitive (though mail systems often treat it as insensitive). A validator that lowercases the local part before storing it is making an assumption that may break User@gmail.com if the user registered as user@gmail.com.
Why Regex Cannot Validate Email
This is the canonical email regex that appears in thousands of codebases:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
The problems:
- Rejects valid special characters (
!,#,$,&,',*,?,^, etc.) - Rejects quoted strings entirely
- Allows consecutive dots in the local part (the
+quantifier matchesa..b) - Allows leading/trailing dots in the local part
- The
{2,}TLD requirement is wrong — TLDs can be 1 character (e.g..q) or very long (e.g..cancerresearch) - Does not handle internationalized domain names (IDN)
The only correct way to validate an email address is:
- Use a proper parser that implements RFC 5322
- Or verify deliverability by sending a confirmation email
Regex is useful for a quick sanity check (does this string contain an @?) but cannot be the sole validation mechanism for conformance.
The CFWS Problem
RFC 5322 defines CFWS (Comment and Folding White Space) — a mechanism that allows comments and folding whitespace in various positions in an email address. This means the following is technically valid per RFC 5322:
user (this is a comment) @example.com
No real mail system generates addresses with comments. But parsers that implement the full RFC grammar must accept them. This is listed as "obs-" (obsolete) in practice but the RFC still requires acceptance.
As a tester, you don't need to generate these — but you should know they exist because a strict validator that rejects them is technically non-conformant.
Practical Test Suite for Email Validation
From everything in this module, here is the minimum test suite for any email validator:
| Input | Expected | Reason |
|---|---|---|
user@example.com |
valid | baseline |
user+tag@example.com |
valid | + is valid atext |
user_name@example.com |
valid | _ is valid atext |
user!name@example.com |
valid | ! is valid atext |
very.common@example.com |
valid | dots are valid between atext |
"user name"@example.com |
valid | quoted string local part |
.user@example.com |
invalid | leading dot |
user.@example.com |
invalid | trailing dot |
user..name@example.com |
invalid | consecutive dots |
user @example.com |
invalid | space without quoting |
user@example |
varies | no TLD — RFC allows, practice varies |
user@.example.com |
invalid | domain starts with dot |
@example.com |
invalid | empty local part |
user@ |
invalid | empty domain |
| 65+ char local part | invalid | exceeds RFC 5321 limit |
| 320+ char full address | invalid | exceeds RFC 5321 limit |
Challenge: Local Part Lab
The practice challenge for this module focuses specifically on the local part. You will submit email addresses and observe how the validator classifies them — valid, invalid with an error, or invalid in a way that reveals a bug (the validator rejects something RFC 5322 explicitly permits).
Use the atext character list and the dot rules to guide your exploration.