Endereços de e-mail internacionalizados podem falhar no cadastro por causa de IDNs, normalização Unicode e lacunas do SMTPUTF8. Aprenda etapas seguras de validação.

Uma regex só pode julgar a forma do texto, não se o domínio consegue realmente receber e-mails ou se sua cadeia de envio consegue entregar para esse endereço. Regexes também tendem a ser ou muito restritivas, bloqueando domínios internacionalizados válidos, ou muito permissivas, aceitando entradas que vão bounces ou falhar posteriormente.
Se você tem audiência global, permitir Unicode na parte do domínio costuma ser seguro porque ele pode ser convertido para uma forma ASCII para checagens DNS. Unicode na parte local (antes do @) é uma decisão maior: verifique se toda a sua rota de envio suporta SMTPUTF8; caso contrário, você corre o risco de cadastros que não recebem verificações ou resets.
Mantenha o que o usuário digitou para exibição, mas converta o domínio para sua forma ASCII antes de fazer consultas DNS ou MX. Armazenar a forma ASCII junto com a original ajuda a deduplicar de forma consistente e evita incompatibilidades entre bibliotecas que tratam IDNs diferentemente.
Normalize cedo, idealmente antes de validar, comparar ou checar unicidade, para que entradas visualmente idênticas não criem contas separadas. NFC é um padrão prático porque reduz problemas de “mesma aparência, bytes diferentes” sem reescrever caracteres tão agressivamente quanto a normalização de compatibilidade.
Faça lowercase na parte do domínio porque, na prática, nomes de domínio são insensíveis a maiúsculas e isso evita duplicados. Evite transformar em minúsculas a parte local por padrão, pois isso pode mudar o significado em sistemas que a tratam como sensível a maiúsculas e minúsculas, e também pode surpreender com regras de caixa em Unicode.
Armazene tanto a entrada original quanto uma forma canônica usada para comparações, busca e restrições de unicidade. A forma canônica costuma ser a string aparada, normalizada em NFC, com o domínio em minúsculas e convertido para ASCII quando necessário; a versão de exibição permanece amigável ao usuário.
Faça primeiro uma checagem de sintaxe, depois verifique se o domínio é resolvível e procure registros MX usando a versão ASCII do domínio. Isso captura erros de digitação e domínios mortos cedo, mas ainda não prova que a caixa existe, então combine isso com confirmação de propriedade do e-mail.
Na maioria das vezes, falha por causa do caminho de envio, não porque seu app aceitou o e-mail. Uma causa comum é a falta de suporte a SMTPUTF8 em algum ponto entre seu app, seu provedor de e-mail e relays intermediários, o que pode quebrar a entrega para partes locais Unicode mesmo quando o endereço é válido.
Remova apenas espaços óbvios ao redor, mas seja cuidadoso com “limpezas” que eliminam caracteres invisíveis que podem ser significativos em Unicode. Também é útil detectar e alertar sobre caracteres ocultos, como espaços sem quebra ou caracteres de largura zero, para que o usuário corrija a entrada em vez de ser bloqueado silenciosamente.
Use-o para substituir lógica de validação frágil e inconsistente por uma única chamada de API que verifica sintaxe conforme RFC, valida domínio, procura registros MX e sinaliza entradas de risco como provedores descartáveis. É especialmente útil quando você quer decisões rápidas e consistentes no cadastro sem manter um pipeline multi-etapas internamente.
Um endereço de e-mail pode parecer normal e ainda assim falhar no momento em que chega a um sistema real. A maior razão é que o que as pessoas veem como um caractere pode ser armazenado como bytes diferentes, tratado de forma distinta por bibliotecas ou rejeitado por servidores de e-mail antigos.
Um exemplo comum é algo como søren@exämple.com. Pode ser um endereço legítimo, mas toca vários pontos frágeis ao mesmo tempo: Unicode na parte local, um nome de domínio internacionalizado e uma infraestrutura de e-mail que pode ou não suportar isso.
As falhas também aparecem longe do seu formulário de cadastro. Você pode aceitar o endereço e depois falhar ao enviar um reset de senha porque seu provedor de e-mail (ou um relay intermediário) não suporta SMTPUTF8. Ou sua regex aceita, mas o passo de "converter para minúsculas e aparar" o transforma em algo diferente do que o usuário pretendia.
Rejeições falsas são caras porque geralmente são silenciosas. Pessoas abandonam cadastros, tentam com outro e-mail ou abrem tickets de suporte difíceis de reproduzir. Se você tem audiência global, rejeitar endereços internacionalizados também pode parecer que você simplesmente não dá suporte ao idioma delas.
Aceitar por engano custa de outra forma. Endereços ruins geram bounces, pioram a entregabilidade e sujam suas listas. Algumas entradas com aparência válida são deliberadamente maliciosas: domínios descartáveis, contas de função usadas para abuso ou armadilhas de spam que prejudicam a reputação do remetente.
O objetivo não é "aceitar tudo" nem "bloquear tudo". É aceitar usuários reais enquanto para entradas obviamente ruins, usando checagens que reflitam como e-mail funciona de verdade: separar exibição de armazenamento, verificar alcançabilidade do domínio (não só a presença do @) e evitar transformações agressivas que reescrevem silenciosamente o que o usuário digitou.
Um endereço de e-mail tem duas partes separadas por @: a parte local (antes do @) e o domínio (depois do @). Endereços internacionalizados podem incluir caracteres Unicode em qualquer uma das partes, e o suporte no mundo real varia conforme qual lado usa Unicode.
O caso mais comum é um nome de domínio internacionalizado (IDN). O usuário vê um domínio escrito no seu script, como maria@bücher.example ou li@例子.公司. Por baixo, muitos sistemas convertem esse domínio para uma forma ASCII (frequentemente chamada de punycode) para que consultas DNS e checagens de MX funcionem de forma confiável.
O caso mais complicado é Unicode na parte local, como jó[email protected] ou ユーザー@domain.com. Isso entra na Email Address Internationalization (EAI) e geralmente é entregue usando SMTPUTF8. Mesmo se o endereço for válido pelos padrões modernos, alguns servidores de e-mail, bibliotecas antigas e ferramentas a jusante ainda rejeitam. Isso significa que você pode aceitá-lo no cadastro e ainda falhar depois, ao tentar enviar.
Uma maneira prática de pensar sobre o suporte hoje:
Por isso uma regex simples de sim/não não basta. Uma regex pode rejeitar usuários legítimos (por exemplo, bloqueando não-ASCII de forma indiscriminada) ou aceitar endereços que você na prática não consegue entregar.
Melhor validação trata cada lado separadamente. Para o domínio, normalize e converta para ASCII para checagens DNS. Para a parte local, você precisa de uma decisão de política: vocês suportam SMTPUTF8 totalmente, permitem com aviso ou bloqueiam porque sua pilha de e-mail não entrega de forma confiável?
Um IDN (Internationalized Domain Name) é um domínio que usa caracteres não ASCII, como acentos ou scripts não latinos. Pessoas veem e digitam a forma Unicode, mas o DNS é construído em torno de ASCII. Esse desalinhamento é onde muitos bugs em produção começam.
Para buscar registros MX, verificar um domínio ou até fazer uma checagem DNS básica, geralmente você precisa da forma ASCII do domínio. Essa conversão é feita com regras IDNA e produz punycode, que frequentemente começa com xn--. Então um usuário pode digitar um domínio que parece normal para ele, mas seus logs, banco de dados ou provedor a montante podem mostrar uma versão xn--....
Punycode aparece em lugares que você deve prever e tratar:
Dois erros comuns:
Há também um ângulo de segurança. Scripts mistos e caracteres confusíveis podem ser usados para criar domínios que se parecem visualmente com uma marca confiável. Geralmente você não deve bloquear todos os IDNs por causa disso, mas é razoável tratá-los como maior risco em contextos como pagamentos, resets de senha ou acesso administrativo.
Uma abordagem prática é aceitar o que o usuário digita e então normalizar internamente:
Unicode permite digitar nomes e palavras de muitas línguas, mas também significa que o "mesmo" caractere pode ser representado de mais de uma maneira. Se você comparar strings por bytes brutos, ou armazenar uma forma e depois receber outra, pode ter duplicados, logins falhos e confusos erros de "e-mail já em uso".
Um exemplo simples é caracteres acentuados. A letra "é" pode ser um único ponto de código (U+00E9) ou dois pontos de código: "e" (U+0065) mais um acento combinante (U+0301). Para uma pessoa parecem idênticos, mas seu banco de dados pode tratá-los como diferentes.
Normalização converte texto para uma forma consistente.
Para o tratamento de e-mail, NFC costuma ser o padrão mais seguro para comparações de "tornar iguais".
Regras de caixa diferem entre os dois lados do endereço:
@): é seguro tratar como insensível a maiúsculas; converter para minúsculas aqui é padrão.@): é tecnicamente sensível a maiúsculas, embora muitos provedores ignorem a caixa. Converter para minúsculas pode mesclar dois endereços distintos em alguns sistemas.Uma abordagem prática: normalize e converta para minúsculas o domínio; mantenha a parte local como o usuário a inseriu, mas armazene também uma forma canônica para comparações.
Normalize nos momentos em que a consistência importa:
Mesmo com um bom serviço de validação, seu app precisa de uma política clara de normalização e de caixa para que usuários legítimos não sejam bloqueados por diferenças invisíveis de caracteres.
A maioria dos bugs com endereços internacionalizados acontece nas junções, onde um sistema assume algo diferente do próximo. O endereço parece bem para um usuário, mas algo na cadeia o altera, rejeita ou trata dois valores com aparência idêntica como diferentes.
Uma falha comum começa no formulário de cadastro. Regras no frontend frequentemente permitem apenas A-Z, 0-9 e alguns símbolos. Teclados móveis inserem pontuação inteligente e o preenchimento automático adiciona um espaço final que você não vê. Auto-conversão para minúsculas também pode se comportar de maneira estranha fora do ASCII básico.
No backend, pequenos passos de limpeza podem ser destrutivos. Aparar é bom, mas remover "caracteres não imprimíveis" pode deletar marcas Unicode válidas. Limites de comprimento são outro problema silencioso: domínios internacionalizados podem crescer quando convertidos para punycode, e você pode atingir um limite inesperado.
Bancos de dados adicionam suas próprias armadilhas. Collation e regras de comparação decidem se duas strings são iguais. Se um sistema armazena uma forma composta e outro mais tarde envia uma forma decomposta, checagens de unicidade podem falhar. Isso cria contas duplicadas ou bloqueia um usuário porque sua consulta de "já existe" não bate com o que foi armazenado.
Problemas aparecem com mais frequência em:
E-mail de saída é onde se torna inevitável. Se seu servidor de e-mail ou um relay a jusante não suporta SMTPUTF8, ele pode recusar enviar para uma caixa com caracteres não ASCII na parte local. Usuários conseguem se cadastrar, mas nunca recebem e-mails de verificação.
Uma cadeia de falha realista é assim: um usuário se registra com um domínio Unicode, seu app o armazena, seu CRM normaliza de forma diferente e seu provedor de e-mail recusa SMTPUTF8. Agora você tem um usuário, duas strings que não batem e um e-mail de boas-vindas que nunca chega.
Um fluxo mais seguro começa separando dois objetivos: não bloquear pessoas reais no cadastro e armazenar algo que você possa comparar, enviar e dar suporte depois.
Preserve a entrada do usuário. Mantenha o endereço exatamente como foi digitado, e remova apenas espaços óbvios nas extremidades. Evite edições "úteis" como mudar caixa, remover acentos, deletar pontos ou tirar tags de mais. Essas mudanças podem transformar silenciosamente um endereço em outro.
Faça uma checagem real de sintaxe. Trate como "isso é estruturalmente possível?", não como "o e-mail definitivamente vai funcionar". Regras modernas são mais amplas que a maioria das regexes, especialmente quando caracteres internacionais estão envolvidos.
Decida sobre normalização e unicidade. Armazene o endereço bruto mais uma forma canônica (frequentemente NFC) para checagens de igualdade. Se o e-mail é chave única no seu sistema, documente se entradas visualmente idênticas mas codificadas de forma diferente contam como a mesma conta.
Trate o domínio corretamente. Normalize o domínio e converta para ASCII (punycode) antes de qualquer trabalho com DNS. Depois verifique o domínio e cheque registros MX (e possivelmente fallback para A/AAAA se sua política permitir).
Tenha uma política para partes locais Unicode. Se seu provedor de saída não entrega SMTPUTF8 de forma confiável, aceite o cadastro só se tiver um plano B (verificação in-app, método de contato alternativo ou um aviso claro antes de prometer entrega por e-mail).
Mantenha um pequeno conjunto de logs sobre resultados de validação para que o suporte possa investigar casos extremos sem adivinhar.
Muitas pessoas dizem "validação de e-mail" quando querem dizer "minha mensagem vai alcançar uma pessoa real". Isso é entregabilidade, e você não pode prová-la completamente no cadastro. Com endereços internacionalizados, é ainda mais fácil confundir "parece válido" com "vai funcionar em todos os lugares".
Validação ainda pode dar sinais fortes antes de você armazenar um endereço ou enviar para ele:
Mas validação não garante que a inbox existe ou aceitará sua mensagem. Muitos provedores bloqueiam sondagens em caixas, aceitam mail para usuários desconhecidos e só devolvem bounce depois, ou mudam políticas sem aviso.
Uma abordagem mais segura é em duas etapas:
Para resultados de "alto risco", bloqueios rígidos costumam criar falsos negativos. Atrito suave tende a funcionar melhor: permita o cadastro, exija confirmação antes de ações críticas ou peça um sinal extra apenas quando o risco for alto.
A forma mais rápida de perder cadastros reais é tratar tudo fora do ASCII simples como inválido. Muitos provedores legítimos suportam domínios internacionalizados e alguns usuários dependem deles.
Muito código em produção ainda assume que e-mail significa A-Z, 0-9, pontos e uma lista curta de símbolos. Isso quebra para domínios IDN e garante rejeições falsas em produtos globais.
Converter o domínio para minúsculas é ok. Converter a parte local pode ser arriscado.
A normalização ajuda, mas fazê-la sem critério pode surpreender usuários. Normalize intencionalmente, mantenha a entrada original e teste como sistemas a jusante se comportam.
Transformações “úteis” que falham:
Seu backend pode precisar de punycode para checagens DNS, mas a interface do usuário deve normalmente exibir o domínio no script do usuário. Mostrar xn--... em confirmações ou mensagens de erro costuma parecer suspeito, mesmo quando o endereço está correto.
Mesmo que um endereço seja válido pela especificação, nem todo servidor suporta SMTPUTF8. Se você aceita partes locais Unicode, esteja preparado para diferenças de entregabilidade entre provedores.
Copiar e colar introduz espaços inseparáveis, caracteres de largura zero e espaços em branco estranhos ao redor do @. Usuários não conseguem ver esses problemas, mas sua validação sim.
Exemplo: um usuário cola name@пример.рф com um espaço final. Se você validar antes de aparar, rejeita. Se você sanitiza demais, pode alterar a parte local.
Endereços internacionalizados podem funcionar de ponta a ponta, mas apenas se todas as camadas concordarem sobre o que aceitar, armazenar e enviar. Antes do release, rode checagens que reflitam o comportamento de produção, não apenas testes unitários.
Assegure que logs e ferramentas administrativas exibam a versão amigável ao usuário sem transformar em mojibake ou quebrar exportações. Confirme também que todo sistema que toca o endereço pode lidar com ele: eventos de analytics, sincronização com CRM, payloads de webhooks, exportações CSV e ingestão em data warehouse. Muitas falhas acontecem na exportação, não na entrada.
Um teste concreto: faça passar o mesmo endereço por cadastro, login, reset de senha e qualquer fluxo de merge de conta. Se passar no cadastro e falhar depois, há um desalinhamento na normalização, armazenamento ou comparações.
Um usuário se cadastra com marta@bücher.example. Parece normal porque o domínio está em Unicode. Seu sistema precisa tratar o domínio como um IDN.
No lado do domínio, mantenha a exibição amigável ao usuário, mas valide a forma segura para o DNS. Converta bücher.example para punycode (xn--bcher-kva.example) antes de fazer buscas MX. Se você só checar a forma Unicode, algumas bibliotecas DNS podem falhar ou se comportar de forma inconsistente.
Agora a parte sutil: o mesmo e-mail pode ser digitado de múltiplas maneiras que parecem idênticas. Suponha que a usuária digite márta@bücher.example, mas o "á" pode ser composto como um único caractere ou como "a" mais um acento combinante. Se você armazenar apenas a entrada bruta, uma pessoa pode acabar com duas contas que parecem iguais na sua UI.
A normalização corrige isso. Normalize para NFC antes de comparar, armazenar, limitar taxa ou desduplicar, e aplique os mesmos passos em todos os lugares que o endereço for tocado.
A parte local (tudo antes do @) é onde você precisa de uma política clara. SMTPUTF8 permite partes locais Unicode, mas nem todo provedor as suporta de ponta a ponta. Uma política prática para muitos produtos é:
Se você quiser um único lugar para executar checagens de sintaxe mais verificação de domínio e MX (e filtrar provedores descartáveis), um serviço de validação de e-mail como Verimail (verimail.co) pode fornecer esses sinais sem depender de uma regex frágil.
Próximos passos que mantêm você seguro sem rejeitar usuários reais: