Which Characters Are Allowed in an Email Address? The RFC List
An email address can contain letters, digits and 19 symbols before the @ without quoting, ! # $ % & ' * + - / = ? ^ _ ` { | } ~, plus the dot, which can't be first, last or doubled. After the @, only letters, digits, hyphens and dots are allowed, and no label can start or end with a hyphen. Spaces and other symbols are legal only inside a quoted local part, which you should rarely accept.
That's the short answer from RFC 5322 (message format) and RFC 5321 (SMTP). Below is the full list, the rules people get wrong, and what five common validators did with each of 33 symbols when we tested them on 6 October 2026.
The parts of an address
An address is a local part, an @, and a domain. Each part has its own character set.
jane.o'brien+news @ mail.example.co.uk
└──── local part ─┘ └──── domain ──────┘
The local part is interpreted only by the receiving server. RFC 5321 section 2.3.11 says the local part "MUST be interpreted and assigned semantics only by the host specified in the domain part of the address". The domain follows DNS hostname rules. Length limits (64 octets for the local part, 254 characters for the whole address) are covered in why email validation regex fails.
Before the @: the unquoted local part
Letters A to Z and a to z, digits 0 to 9, 19 symbols, and dots between them.
RFC 5322 section 3.2.3 defines these as atext: "Printable US-ASCII characters not including specials".
| Character | Name | Example |
|---|---|---|
! |
Exclamation mark | jane!doe@example.com |
# |
Hash | jane#1@example.com |
$ |
Dollar | jane$@example.com |
% |
Percent | jane%doe@example.com |
& |
Ampersand | jane&jo@example.com |
' |
Apostrophe | o'brien@example.ie |
* |
Asterisk | jane*@example.com |
+ |
Plus | jane+news@example.com |
- |
Hyphen | jane-doe@example.com |
/ |
Slash | jane/doe@example.com |
= |
Equals | jane=doe@example.com |
? |
Question mark | jane?@example.com |
^ |
Caret | jane^doe@example.com |
_ |
Underscore | jane_doe@example.com |
` |
Backtick | jane`doe@example.com |
{ } |
Braces | {jane}@example.com |
| |
Pipe | jane|doe@example.com |
~ |
Tilde | jane~doe@example.com |
The dot rule
A dot is allowed only between other characters: never first, never last, never two in a row.
RFC 5321 section 4.1.2 writes the unquoted form as Dot-string = Atom *("." Atom) with Atom = 1*atext. Every dot must have at least one atext character on both sides. So jane.doe@ is valid, while .jane@, jane.@ and jane..doe@ are not. Some old systems issued addresses with those patterns anyway, but they aren't standard.
Gmail ignores dots for delivery, so j.ane@gmail.com and jane@gmail.com are the same inbox. That is Gmail's choice as the receiving host, not a rule of the standard. See plus addressing and free-trial abuse for the deduplication side.
Characters that need quotes
( ) < > [ ] : ; @ \ , . and " are RFC 5322 "specials". Along with spaces, they're only allowed inside a quoted local part.
A quoted local part is wrapped in double quotes: "jane doe"@example.com, "jane@home"@example.com. RFC 5321 defines what may go inside the quotes as qtextSMTP = %d32-33 / %d35-91 / %d93-126. In plain terms, that's "any ASCII graphic or space is permitted without blackslash-quoting except double-quote and the backslash itself". A backslash escapes either of those: "jane\"doe"@example.com.
So it's legal. The same section of RFC 5321 then advises against it: "a host that expects to receive mail SHOULD avoid defining mailboxes where the Local-part requires (or uses) the Quoted-string form". Quoted local parts are rare, and they break CSV exports, CRM imports and plenty of sending tools. Most sites are better off rejecting them with a clear message.
Two more forms from RFC 5322 are valid in message headers but not in the SMTP envelope: comments in parentheses (jane(work)@example.com) and folding whitespace. RFC 5321's Mailbox grammar doesn't include them, so no address you send to should contain them.
Control characters and non-ASCII
ASCII control characters are never allowed. Non-ASCII letters are allowed only under the SMTPUTF8 extension.
RFC 5321 says ASCII control characters (decimal 0 to 31 and 127) "MUST NOT be used in MAIL or RCPT commands". Characters like é or 用 are allowed in the local part only with SMTPUTF8 (RFC 6531), which extends atext to include UTF-8. That needs support from every server involved, as we show in internationalized email addresses.
After the @: the domain
Letters, digits and hyphens in each label, with dots between labels. No label may start or end with a hyphen or be longer than 63 octets.
RFC 5321 section 4.1.2:
Domain = sub-domain *("." sub-domain)
sub-domain = Let-dig [Ldh-str]
Let-dig = ALPHA / DIGIT
Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
Each label has to start and end with a letter or digit, with hyphens allowed only in the middle. The 63-octet label limit comes from DNS (RFC 1035). Underscores aren't allowed in mail domains even though they appear in some DNS records. A trailing dot (jane@example.com.) isn't part of the grammar either. Domains are case-insensitive, so lower-case them before storing or comparing.
The domain can also be an address literal in square brackets: jane@[192.0.2.1] or jane@[IPv6:2001:db8::1]. These are valid, but on a public signup form they're almost always junk or a probe. Reject them.
How five validators handled 33 symbols
All five accepted every atext symbol and rejected every special character, with one exception.
We built jane{X}doe@example.com for each of the 19 atext symbols, the dot, the 12 other specials and a space (33 in all), and ran each through validator.js 13.15.35 isEmail, Chrome 155's <input type="email">, PHP 8.5 filter_var(..., FILTER_VALIDATE_EMAIL), WordPress is_email() (current source) and Apache Commons Validator 1.11.0 EmailValidator.
| Group | validator.js | Chrome | PHP | WordPress | Commons |
|---|---|---|---|---|---|
19 atext symbols and the dot |
All accepted | All accepted | All accepted | All accepted | All accepted |
( ) , : ; < > @ [ ] " and space, unquoted |
All rejected | All rejected | All rejected | All rejected | All rejected |
\ unquoted |
Rejected | Rejected | Rejected | Rejected | Accepted |
Apache Commons Validator accepted jane\doe@example.com, even though a backslash is only valid inside quotes as an escape. If you use it in Java, add your own check for an unquoted backslash. We cover the Java side in validating email in Java.
Where validators disagree is the edge cases. validator.js and Commons accepted "jane doe"@example.com, but PHP's filter_var rejected it. PHP accepted jane@[192.168.0.1], but validator.js rejected it unless you pass allow_ip_domain: true. Test your validator against the cases you care about rather than assuming it follows the RFC.
What mailbox providers allow is narrower
Providers restrict the characters in the addresses they hand out, but your form has to accept the full set, because custom domains can use any of it.
Google's Gmail username rules allow only "letters (a-z), numbers (0-9), and periods (.)", 6 to 30 characters, and say usernames "cannot contain an ampersand (&), equals sign (=), underscore (_), apostrophe ('), dash (-), plus sign (+), comma (,), brackets (<,>), or more than one period (.) in a row". Gmail still delivers to jane+news@gmail.com, because plus addressing is handled when mail arrives, not at sign-up.
Rules like these only cover addresses at that provider. A company domain or a self-hosted mail server can issue addresses with apostrophes, hyphens, underscores or any other atext character. Never validate a business address against Gmail's rules.
What to accept on a real form
Accept the whole unquoted standard and IDN domains. Reject quoted local parts, comments and IP literals.
| Input | Recommendation | Why |
|---|---|---|
Any atext symbol, including ' + / = |
Accept | Valid, and real people use them |
| Uppercase letters | Accept, keep as typed | Compare in lower case |
| Dot first, last or doubled | Reject | Not valid unquoted |
| Quoted local part | Reject with a specific message | Valid but breaks downstream tools |
| Comments, folding whitespace | Reject | Not valid in SMTP |
[IP] literal domain |
Reject | Not useful on a public form |
| Non-ASCII local part | Accept only if your sending path supports SMTPUTF8 | See internationalized addresses |
Valid characters don't make an address deliverable. asdfgh@gmail.com uses only letters, and the mailbox doesn't exist. After the syntax check, an MX lookup and a mailbox check answer the real question. Syntax vs MX vs SMTP explains what each layer catches, and you can try one address in the free email verifier.
Common questions
What special characters are allowed in an email address?
Before the @, RFC 5322 allows letters, digits and these 19 symbols without quoting: ! # $ % & ' * + - / = ? ^ _ ` { | } ~, plus the dot. The dot can't be first, last or doubled. After the @, a domain allows only letters, digits, hyphens and dots between labels, and a label can't start or end with a hyphen.
Can an email address contain a space?
Only inside a quoted local part, such as "jane doe"@example.com. RFC 5321 allows it, but it also says hosts should avoid creating mailboxes that need quoting, and many forms, CRMs and sending tools reject such addresses. In practice almost no real mailbox uses one.
Is an apostrophe allowed in an email address?
Yes. The apostrophe is in the RFC 5322 atext set, so o'brien@example.ie is valid without quoting, and validator.js, Chrome, PHP filter_var, WordPress is_email and Apache Commons Validator all accepted it in our test. Make sure your database queries are parameterised, because the apostrophe is a quote character in SQL.
Are uppercase letters allowed in email addresses?
Yes. Domains are case-insensitive. RFC 5321 says the local part may be case-sensitive and leaves that to the receiving server, although almost no large provider treats Jane and jane as different mailboxes. Store the address as typed and compare in lower case.
Check your list before you send
Real mailbox checks over SMTP, and nothing is sent to the address. Sign in with Google and your first 100 email checks are free, no card. Plans for bigger lists are on the pricing page.