Form vs SMTP Email Validator

Paste email addresses and see whether the browser's type=email rule, RFC 5322 and RFC 5321 each accept them, which rule decided each verdict, and the quoted form SMTP needs when they disagree. Syntax only. Everything runs in this tab.

1. Check addresses

One address per line. Each line is checked exactly as typed, never trimmed, so a stray space is part of the address. Blank lines are skipped. Lines over 2000 characters are refused.

Out of scope, because each line is one address: comma separated lists (type=email multiple, RFC 5322 address-list), display names with angle brackets, and header folding across lines.

2. Type into a real type=email field

This is an ordinary <input type="email">. Whatever this browser does with what you type is shown underneath, read straight from the element. The HTML Standard says user agents "should convert punycode in the domain labels of the value to IDN in the display and vice versa", so a domain typed with accents may come back as xn-- labels in .value. This page reports what this browser returns and does not predict it.

3. How each column decides

A. Browser form rule (HTML Standard, valid email address)

The HTML Standard, section "Email state (type=email)", defines a valid email address and gives this regular expression as an implementation of it. Column A runs it verbatim:


The same section says outright that it departs from RFC 5322:

"This requirement is a willful violation of RFC 5322, which defines a syntax for email addresses that is simultaneously too strict (before the "@" character), too vague (after the "@" character), and too lax (allowing comments, whitespace characters, and quoted strings in manners unfamiliar to most users) to be of practical use here."

Because the rule allows any run of dots before the @, it accepts .john@, a..b@ and john.@, which neither RFC accepts. Because it has no quoted strings, comments or address literals, it rejects "john doe"@example.com and user@[192.0.2.1], which both RFCs accept. The explanation under each verdict comes from a separate hand written checker, and the self test fuzzes that checker against the regex so the two can never drift apart.

B. This browser, live

Each line is assigned to a detached input type=email and the page reads back validity.valid, validity.typeMismatch and .value. The value sanitization algorithm for a single address is "Strip newlines from the value, then strip leading and trailing ASCII whitespace from the value", so a line with spaces around it can be rejected by the regex in column A and accepted here. When the value changes, the column shows what it became. The column is labelled with this browser's own user agent string, and nothing in it is precomputed.

C. RFC 5322 addr-spec (message format)

RFC 5322 is the grammar for addresses inside a message, in header fields such as From: and To:. It is not the SMTP grammar. Column C is a recursive descent parser, not one large regular expression, because comments nest without limit and a backtracking regex for them can take exponential time. There are four outcomes:

  • VALID: a dot-atom or quoted-string, @, then a dot-atom or domain-literal, with no comments or white space outside them.
  • VALID ONLY WITH COMMENTS OR FOLDING WHITE SPACE: the section 3 grammar matches only because of CFWS (section 3.2.2), such as john(comment)@example.com. Section 3.4.1: "Comments and folding white space SHOULD NOT be used around the "@" in the addr-spec."
  • VALID ONLY UNDER OBSOLETE SYNTAX: matches only with section 4.4 obs-local-part or obs-domain, or the section 4.1 obsolete characters. Section 4 says these forms "MUST NOT be generated" and "MUST be accepted and parsed by a conformant receiver".
  • INVALID: none of the above.
addr-spec       =   local-part "@" domain
local-part      =   dot-atom / quoted-string / obs-local-part
domain          =   dot-atom / domain-literal / obs-domain
domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
quoted-string   =   [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
obs-local-part  =   word *("." word)
obs-domain      =   atom *("." atom)

RFC 5322 sections 3.2.1 to 3.2.4, 3.4.1 and 4.4. One line holds one address, so folding white space here is a run of spaces or tabs; there is no CRLF to fold on. When a quoted local part could have been written as a dot-atom, the results note section 3.4.1: "the dot-atom form SHOULD be used and the quoted-string form SHOULD NOT be used".

D. RFC 5321 Mailbox (SMTP envelope)

RFC 5321 is the grammar for the address an SMTP client sends in MAIL FROM and RCPT TO. It has no comments, no white space and no obsolete forms, and its domain is a hostname or an address literal.

Mailbox        = Local-part "@" ( Domain / address-literal )
Local-part     = Dot-string / Quoted-string
Dot-string     = Atom *("."  Atom)
Quoted-string  = DQUOTE *QcontentSMTP DQUOTE
qtextSMTP      = %d32-33 / %d35-91 / %d93-126
quoted-pairSMTP  = %d92 %d32-126
Domain         = sub-domain *("." sub-domain)
sub-domain     = Let-dig [Ldh-str]
IPv4-address-literal  = Snum 3("."  Snum)
IPv6-address-literal  = "IPv6:" IPv6-addr
General-address-literal  = Standardized-tag ":" 1*dcontent

RFC 5321 sections 4.1.2 and 4.1.3. The checks the ABNF alone does not make, and that this column does:

  • Snum is 0 to 255, from the ABNF comment, so [300.1.1.1] is invalid here and valid RFC 5322 (where dtext takes any printable character).
  • IPv6-comp allows "No more than 6 groups in addition to the "::"", and IPv6v4-comp no more than 4 plus the IPv4 part. IPv6-full is exactly 8 groups. The IPv6: tag is matched in any case because RFC 5234 section 2.3 says "ABNF strings are case insensitive".
  • General-address-literal: the tag "MUST be specified in a Standards-Track RFC and registered with IANA". The IANA Address Literal Tags registry listed only IPv6 when it was checked on 2026-10-01, so any other tag, such as the dead in cow@[dead::beef], is reported INVALID (unregistered tag).
  • Underscore in a hostname: section 4.1.2, "the underscore character is not permitted".

E. Translation

RFC 5321 section 4.1.2: "all quoted forms MUST be treated as equivalent, and the sending system SHOULD transmit the form that uses the minimum quoting possible". Column E takes the local part's content (quotes removed, quoted-pairs unescaped, comments dropped), then:

  1. if the content is a valid Dot-string, it is sent unquoted;
  2. otherwise, if every character is printable ASCII or space, it is wrapped in double quotes, with " and \ escaped by a backslash, so .john@example.com becomes ".john"@example.com, which is a valid RFC 5321 Mailbox;
  3. otherwise there is no RFC 5321 form: non-ASCII needs SMTPUTF8 (RFC 6531) and control characters have none.

It also goes the other way. When the browser rule rejects an address whose content uses only characters the rule allows, the column shows the spelling the form would accept: "john..doe"@example.com becomes john..doe@example.com. Address-literal domains have no form side spelling, and hostnames with an underscore, a ! or a leading hyphen have no SMTP spelling.

4. 64, 255, 256 and 254 are not validity limits

RFC 5321 section 4.5.3.1 lists the local-part at 64 octets (4.5.3.1.1), the domain at 255 octets (4.5.3.1.2) and the path at 256 octets "including the punctuation and element separators" (4.5.3.1.3). It frames them as a floor for receivers, not a rule about syntax: "Every implementation MUST be able to receive objects of at least these sizes. Objects larger than these sizes SHOULD be avoided", and clients "MUST be prepared for a server to reject them". So this page reports an oversize address as exceeding the size every server must accept, and never as invalid. Lengths are counted in octets of UTF-8, not in characters.

The figure 254 is not in RFC 5321. It comes from RFC 3696 (Informational, February 2004) erratum 1690, status Verified, which derives it from the 256 octet path minus the two angle brackets in Path = "<" [ A-d-l ":" ] Mailbox ">". The erratum text itself refers to RFC 2821, the predecessor of RFC 5321.

A hostname label longer than 63 octets matches the RFC 5321 ABNF, which sets no length, but cannot exist in DNS: RFC 1035 section 2.3.4, "labels 63 octets or less". The browser rule rejects it through its {0,61}.

Two more notes the results add when they apply. A single label domain such as user@localhost is valid in all three grammars, but RFC 5321 section 2.3.5 says "Only resolvable, fully-qualified domain names (FQDNs) are permitted" and "Local aliases MUST NOT appear in any SMTP transaction". And an uppercase local part matters: section 2.4, "The local-part of a mailbox MUST BE treated as case sensitive". Domains are not.

Non-ASCII addresses are invalid in all three base grammars. The RFC 6532 section 3.2 extension (atext, qtext, dtext =/ UTF8-non-ascii) and the RFC 6531 section 3.3 extension (atext, qtextSMTP =/ UTF8-non-ascii, sub-domain =/ U-label) would allow some of them, and the results say so. This page does not perform the RFC 5890 IDNA2008 check a U-label needs, so it never calls a non-ASCII domain valid under RFC 6531.

5. What to use it for

  • A signup form refused a real address. Paste it. If column A rejects and column D accepts, the address is deliverable over SMTP and the form rule is the obstacle. Column E gives the spelling the form would take, when one exists.
  • Your form accepted an address your mail server cannot send to. Addresses such as .john@ or a..b@ pass the browser rule and fail RFC 5321. Column E gives the quoted form, ".john"@example.com, to try in the SMTP envelope.
  • Choosing the right check for the right layer. The form, the message header and the SMTP envelope are three different grammars. Paste your own test cases and see which layer each one breaks.
  • Writing tests for a validator. Load every fixture, and copy any row whose verdicts surprise you into your own test suite with the deciding rule beside it.
  • Checking what this browser does. Column B and section 2 show this browser's own validity flags and value sanitization, measured now rather than quoted from a table.

What it cannot do: it checks syntax only. It does no DNS or MX lookup, makes no network call, and cannot tell whether a mailbox exists or accepts mail.

6. Self test

Runs when the page loads. It checks every engine against fixtures derived by hand from the ABNF, fuzzes the column A explainer against the verbatim regex, the column D parser against a separately built regular expression for RFC 5321, and the column C parser against separately built regular expressions for RFC 5322 with comments nested at most three deep. It includes a check designed to fail, so a test that silently stops running is visible, and it feeds pathological 2000 character lines through every engine to show none of them hangs. The live browser column is reported, never asserted.