Great work!

XP to next level

BugEater

Special Characters and Quoted Strings

RFC 5322 allows a wider range of characters in email local parts than most developers or validators expect. This lesson catalogs exactly what is and isn't allowed, and shows how to test for over-restrictive validators.

The Complete atext Character Set

In the dot-atom (unquoted) local part form, the allowed characters are defined as atext in RFC 5322 section 3.2.3:

atext = ALPHA / DIGIT /  "!" / "#" / "$" / "%" / "&" / "'" /
        "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" /
        "`" / "{" / "|" / "}" / "~"

Expanded, the complete list of allowed symbols (non-alphanumeric):

! # $ % & ' * + - / = ? ^ _ ` { | } ~

All of these are valid in an unquoted email local part.

The characters NOT in atext (and therefore requiring quoting or being invalid entirely):

( ) [ ] \ , ; : < > @ space

Double quote " cannot appear unquoted either — it would be interpreted as the start of a quoted string.

Testing Each Special Character

The systematic test: for each special character in atext, construct a minimal email using only that character in the local part and verify it is accepted:

Local part Full address Should be
user!name user!name@example.com valid
user#name user#name@example.com valid
user$name user$name@example.com valid
user%name user%name@example.com valid
user&name user&name@example.com valid
user'name user'name@example.com valid
user*name user*name@example.com valid
user+name user+name@example.com valid
user-name user-name@example.com valid
user/name user/name@example.com valid
user=name user=name@example.com valid
user?name user?name@example.com valid
user^name user^name@example.com valid
user_name user_name@example.com valid
user`name user`name@example.com valid
user{name user{name@example.com valid
user\|name user\|name@example.com valid
user}name user}name@example.com valid
user~name user~name@example.com valid

Any rejection from this list is a validator defect.

The Quoted String Form

When the local part is enclosed in double quotes, the constraints change dramatically. Inside quotes:

  • Spaces are allowed: "user name"@example.com
  • Most special characters that are normally forbidden are allowed: "user(name)"@example.com
  • The @ symbol is allowed: "user@alias"@example.com
  • Backslash-escaped characters are allowed: "user\"name"@example.com

The quoted string rules:

  • The entire local part must be wrapped in quotes (not just part of it)
  • Inside quotes, " and \ must be escaped: \" and \\
  • Printable ASCII characters (except " and \) do not need escaping

This is the most commonly unsupported valid form. Real mail addresses using quoted local parts are vanishingly rare, but per the RFC, they must be accepted by conformant parsers.

Dot Rules in Detail

Even with the full atext character set, dots have specific rules:

Rule 1: No dot at the start of the local part

  • .user@example.com — invalid
  • . user@example.com — invalid

Rule 2: No dot at the end of the local part

  • user.@example.com — invalid
  • user. @example.com — invalid

Rule 3: No two consecutive dots

  • user..name@example.com — invalid
  • user.name..more@example.com — invalid

Valid uses of dots:

  • user.name@example.com — single dot between words
  • user.middle.name@example.com — multiple single dots
  • first.last+tag@example.com — dots combined with other specials

The Most Common Validator Failure

Based on real-world testing of production applications, the most commonly rejected valid characters are:

  1. + (plus sign) — rejected by roughly 30% of email validators
  2. ' (apostrophe) — rejected by about 25%
  3. = (equals sign) — rejected by about 20%
  4. ! (exclamation mark) — rejected by about 15%
  5. Quoted strings — rejected by nearly all simple regex validators

The + case is particularly impactful because Gmail's address tagging feature (user+newsletter@gmail.com) is widely used and involves real addresses that your users will submit.

What to Include in Your Test Suite

At minimum, test these cases for any email validation:

  1. user+tag@example.com — plus sign (most commonly broken)
  2. user_name@example.com — underscore
  3. user.name@example.com — dot (valid use)
  4. .user@example.com — leading dot (should fail)
  5. user.@example.com — trailing dot (should fail)
  6. user..name@example.com — consecutive dots (should fail)
  7. "user name"@example.com — quoted string (should succeed per RFC; often fails)

Quiz

The email address "john doe"@example.com contains a quoted local part with a space. Is it valid per RFC 5322?

A system rejects user..name@example.com (two consecutive dots in the unquoted local part). Is this correct?

An application accepts user@example.com but rejects user.@example.com (a dot immediately before @). How should the tester classify this?

A user submits "(),:;<>[]"@example.com. These characters are invalid in an unquoted local part. Is this address valid per RFC 5322?