SMTPUTF8 Email Addresses: What Your Signup Form Should Accept
Your signup flow needs two separate decisions for an internationalized email address.
A Unicode domain with an ASCII local part should move through IDNA conversion before DNS. A non-ASCII local part needs SMTPUTF8 support across the mail path. Mixing those cases under one “Unicode email” flag produces false rejections.
So what should you do? Preserve the local part, convert the domain to an ASCII A-label for network lookups, record whether SMTPUTF8 is required, and keep an unsupported capability separate from a missing mailbox.
The timing matters. The IETF Mail Maintenance Working Group published SMTPUTF8 Email Addresses draft 04 on July 6, 2026. It proposes a narrower address syntax meant to reduce confusing Unicode combinations.
It is an Internet-Draft, not an RFC, and it has no enforcement date. I would treat it as design direction, not a new production mandate.
What problem is the new draft trying to fix?
RFC 6532 permits Unicode in email addresses and message headers. Its flexibility also permits strings which look different from what software extracts or stores.
Draft 04 proposes three restrictions for addresses in message headers:
- An address atom must not contain an A-label such as
xn--dmi-0na. The human-facing form should stay in Unicode. - The address must stay within specified PRECIS and IDNA code-point classes, plus
.and@. - The address must not mix more than one non-ASCII script. ASCII characters do not count toward the script limit.
The draft permits dømi@dømi.fo, where the non-ASCII characters use the Latin script. It rejects a Latin and Han mixture across one address.
A fair objection is simple: a signup form is not an email header parser.
I agree. Your application does not need to enforce a draft word for word. The useful idea is the boundary it exposes. A display form, a DNS lookup form, and an SMTP envelope form are related, but they are not always the same string.
Which part of the address is internationalized?
Split the address at the @ before deciding what support is required.
| Address | What changed | Network requirement |
|---|---|---|
alice@example.com |
Nothing | Ordinary DNS and SMTP |
info@dømi.fo |
Unicode domain only | Convert the domain to xn--dmi-0na.fo for DNS. SMTPUTF8 is not required by the address. |
dømi@dømi.fo |
Unicode local part and domain | IDNA for DNS, plus SMTPUTF8 for the SMTP envelope |
RFC 6531 requires an internationalized domain to go through an IDNA-aware DNS library or A-label conversion. An A-label is the ASCII form beginning with xn--.
The local part follows a different rule. Do not convert it to Punycode. Keep it intact.
Why does the browser reject some valid SMTPUTF8 addresses?
The HTML Living Standard still defines the input type="email" grammar with an ASCII-oriented local part and domain labels. Its reference regular expression contains ASCII ranges only.
So a browser passing an address through native constraint validation does not establish full SMTPUTF8 syntax support. The opposite is also true. A string accepted by a text field has not passed email validation.
If your product supports non-ASCII local parts, test the exact browsers in scope. A text input with inputmode="email", an accessible error message, and server-side validation gives you control over the accepted grammar.
If your product supports only ASCII local parts, say so clearly. “Use an address with English letters before the @” is more honest than “invalid email” for an address your stack chose not to support.
How should a Node.js API separate the two cases?
This example implements a practical signup subset. It rejects quoted local parts and whitespace around the address on purpose. It does not claim to parse every mailbox form in the email RFCs.
import { domainToASCII } from 'node:url'
export function classifySignupEmail(input) {
if (typeof input !== 'string' || input.length === 0) {
return { kind: 'invalid_structure' }
}
if (input !== input.trim() || /[\r\n]/u.test(input)) {
return { kind: 'invalid_structure' }
}
const at = input.indexOf('@')
if (at <= 0 || at !== input.lastIndexOf('@') || at === input.length - 1) {
return { kind: 'invalid_structure' }
}
const local = input.slice(0, at)
const domainUnicode = input.slice(at + 1)
const domainAscii = domainToASCII(domainUnicode)
if (!domainAscii) {
return { kind: 'invalid_domain' }
}
return {
kind: 'address_candidate',
local,
domainUnicode,
domainAscii: domainAscii.toLowerCase(),
requiresSmtpUtf8: /[^\x00-\x7f]/u.test(local)
}
}
Node’s domainToASCII() returns the ASCII serialization of a valid internationalized domain and an empty string for an invalid domain.
Keep the original local part. Do not lowercase it, remove dots, strip plus tags, or apply Unicode normalization unless the mailbox provider owns the rule. Two strings which look equivalent to your application might identify different mailboxes.
Store the A-label domain as a lookup key. Keep the entered form only where your privacy and retention policy needs it.
What does SMTPUTF8 change during verification?
An SMTP server advertises SMTPUTF8 in its EHLO response. RFC 6531 defines the capability keyword and the SMTPUTF8 parameter on MAIL FROM.
S: 250-8BITMIME
S: 250 SMTPUTF8
C: MAIL FROM:<probe@verifier.example> SMTPUTF8
C: RCPT TO:<dømi@dømi.fo>
If the server does not advertise SMTPUTF8, the client must not send an internationalized address. Try every applicable MX host before deciding the route lacks support.
This outcome describes transport capability. It does not prove the named mailbox is absent.
The distinction fits the broader SMTP verification model. A timeout, temporary deferral, policy block, or missing capability should not turn into a made-up mailbox verdict.
Which result should your signup flow return?
| Observed evidence | Meaning | Signup action |
|---|---|---|
| Invalid structure or failed IDNA conversion | Confirmed input failure | Block and ask for a correction |
| No usable MX or address fallback | Confirmed domain-level routing failure | Block and ask for another address |
| Non-ASCII local part, verifier lacks EAI support | Verifier capability gap | Review or ask for an alternate address. Do not label the mailbox missing. |
| All MX hosts omit SMTPUTF8 | Current mail route does not accept an SMTPUTF8 envelope | Ask for an alternate address and record the capability result |
SMTPUTF8 advertised, RCPT TO returns 2xx |
Recipient accepted during the probe | Allow under your normal policy. Delivery is still not guaranteed. |
SMTPUTF8 advertised, RCPT TO returns 4xx |
Temporary or inconclusive response | Retry later or review |
RFC 6531 also defines X.6.7 for a non-ASCII sender or recipient rejected by capability policy. Preserve the enhanced status code. It explains more than a bare 550 or 553.
What does emailverifier.dev support today?
I sent two requests to the public emailverifier.dev REST API on August 14, 2026.
An ASCII local part with a Unicode domain was normalized to an A-label before verification:
{
"email": "info@xn--dmi-0na.fo",
"status": "undeliverable",
"action": "block",
"flagged": true,
"signals": ["no_mail_server", "role_address"],
"suggestion": null
}
The result does not reject the Unicode domain syntax. It reports no usable mail server for the normalized domain and separately reports the role-address signal.
A non-ASCII local part returned the current product boundary:
{
"email": "dømi@dømi.fo",
"status": "undeliverable",
"action": "block",
"flagged": true,
"signals": ["invalid_syntax"],
"suggestion": null
}
So, as of August 14, emailverifier.dev supports internationalized domains with ASCII local parts. It does not support SMTPUTF8 local parts. I would rather state the boundary than pretend one API covers every address form.
For supported addresses, the API still separates confirmed failures, risk signals, and unknown results. The production result-handling guide shows how to keep those states apart in application code.
A rollout checklist
- Decide whether your product supports Unicode domains only or full SMTPUTF8 local parts.
- Document the accepted subset in product copy and API errors.
- Preserve the local part exactly.
- Convert the domain through IDNA before DNS.
- Store both the capability requirement and verification outcome.
- Test your frontend, backend, database, queue, mail provider, and confirmation flow with real internationalized addresses.
- Keep unsupported, unknown, risky, and undeliverable as separate states.
- Require inbox confirmation where account recovery or sensitive access depends on control of the address.
Normalize domains. Preserve local parts. Keep capability gaps honest.