Skip to content
Empieza con 100 créditos de verificación gratis
Qualisend
Todos los artículos
Ingeniería / 27 de mayo de 2026

Por qué falla la validación de correo con regex

10 min de lectura

Qualisend team
Por qué falla la validación de correo con regex

Todo código base tiene una: una expresión regular, copiada de Stack Overflow, que «valida» direcciones de correo. Parece una comprobación, pero responde a una pregunta que casi nadie se está haciendo en realidad. Una regex puede decirte que una cadena tiene forma de dirección de correo. No puede decirte si la dirección existe, si acepta correo o si no provocará un rebote definitivo en tu próxima campaña, y eso es lo único que importa.

La respuesta corta#

Una regex valida la sintaxis, no la entregabilidad. definitely-fake@gmail.com es una dirección de correo perfectamente válida según cualquier regex jamás escrita, y rebotará en cuanto le envíes algo. Peor aún: las regex a las que recurre la gente o bien rechazan direcciones reales (demasiado estrictas) o bien aceptan disparates (demasiado laxas), y la que es técnicamente correcta ocupa cientos o miles de caracteres y aun así no puede confirmar un buzón. Usa una comprobación de sintaxis sencilla para detectar erratas de dedo en el input y luego verifica la entregabilidad con una comprobación de DNS y SMTP, que es un problema de red, no de coincidencia de patrones.

La regex que has visto y lo que deja pasar#

Aquí está el arquetipo, alguna variante de esto vive en la mayoría de proyectos:

const re = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
re.test("definitely-fake@gmail.com"); // true  ← will hard-bounce
re.test("typo@gmial.com");            // true  ← typo'd domain, bounces
re.test("info@company-that-folded.com"); // true  ← dead domain

Las tres pasan. Las tres son no entregables. La regex hizo su trabajo a la perfección y no te dijo nada útil, porque la sintaxis y la entregabilidad son preguntas distintas. Cada dirección que una regex puede ver es una cadena; que haya una persona leyendo el correo detrás es un hecho sobre internet, no sobre la cadena.

Ningún patrón puede detectar un dominio mal escrito como gmial.com; eso requiere compararlo con los proveedores conocidos. Consulta las erratas de correo más comunes o prueba el verificador de errores tipográficos gratuito.

Las direcciones que las regex estrictas rechazan por error#

Los patrones estrictos fallan en sentido contrario. Este patrón típico, «más ajustado», rechaza todas las direcciones válidas de la tabla siguiente:

const STRICT = /^[\w.-]+@\w+\.[a-z]{2,4}$/i;
DirecciónSuposición falsaRealidad
jane+news@example.comLa parte local solo admite letras, dígitos, puntos, guiones y guiones bajosEl direccionamiento con signo más es legal; Gmail y muchos otros entregan el correo +tag en el buzón base
o'brien@example.comLos nombres no llevan signos de puntuaciónEl apóstrofo es un carácter legal en la parte local
jane@studio.photographyLos TLD tienen de 2 a 4 letrasTLD largos como .photography llevan años activos
jane@mail.example.co.ukUn dominio es un nombre más un TLD.co.uk y los subdominios de correo añaden etiquetas
jane@my-company.comLos dominios solo tienen letras y dígitosLos guiones son legales dentro de una etiqueta

Cada rechazo es una persona real que se queda fuera al registrarse, y ninguno aparece en tus logs de rebotes, por eso los patrones demasiado estrictos sobreviven durante años. La comprobación de sintaxis de más abajo acepta las cinco.

El laberinto del RFC 5322#

«Vale», dice el razonamiento, «usaré una regex correcta». La gramática formal de una dirección de correo está definida por el RFC 5322, y una regex que realmente la implementa es célebremente monstruosa: de cientos a miles de caracteres, y permite cosas que nunca querrías aceptar, como partes locales entrecomilladas con espacios ("a b"@example.com) y comentarios dentro de la dirección.

De ahí se derivan dos problemas. Primero, la regex estricta acepta más de lo que quieres, no menos: valida contra una especificación de 2008, no contra «direcciones a las que los servidores de correo reales van a entregar». Segundo, ni siquiera una coincidencia impecable con el RFC 5322 puede decirte si el dominio tiene un servidor de correo o si el buzón existe. Has invertido un esfuerzo enorme en responder a la pregunta fácil con más precisión, mientras que la pregunta difícil, ¿llegará el correo?, sigue completamente intacta.

Límites de longitud: 64, 255 y 254#

El RFC 5321, el estándar de SMTP, limita la parte local (antes de la @) a 64 octetos, el dominio a 255 y la ruta completa a 256, incluidos los corchetes angulares que rodean la dirección (<jane@example.com>). Eso deja un techo real de 254 caracteres para la dirección en sí.

Algunas de nuestras guías por lenguaje comprueban length <= 320 (64 + 1 + 255) en su lugar. Es un límite laxo pero inofensivo: todo lo que rechaza es realmente demasiado largo, y cualquier dirección de más de 254 caracteres que deje pasar aún tiene que superar las comprobaciones de DNS y SMTP.

Las tres cosas que una regex fundamentalmente no puede hacer#

Ningún patrón, por ingenioso que sea, puede llegar al otro lado de la red. Una regex no puede:

  • Comprobar que el dominio puede recibir correo. user@company-that-folded.com tiene sintaxis válida sobre un dominio sin registros MX. Solo una consulta DNS revela el dominio muerto.
  • Confirmar que el buzón existe. noreply-9f2x@gmail.com tiene sintaxis válida para una cuenta que nunca se creó. Solo una conversación SMTP con Gmail puede decirte que no está ahí.
  • Detectar un dominio catch-all. Un servidor catch-all acepta todas las direcciones, así que ni siquiera una comprobación SMTP en vivo puede confirmar un buzón concreto, y una regex no tiene ni idea de que el dominio se comporta así.

Estas no son carencias de una regex en particular; están fuera de lo que cualquier regex puede hacer, porque son preguntas sobre servidores, no sobre cadenas. Responderlas es trabajo de la verificación de correo, que pregunta a la red y no a la cadena.

Qué hacer de verdad: validar por capas#

La entregabilidad es una tubería de comprobaciones cada vez más costosas, y la sintaxis es solo la primera etapa, la barata (el panorama completo está en cómo funciona la verificación de correo):

  1. Sintaxis — una comprobación sencilla en el input para detectar erratas evidentes. Esta es la única capa a la que pertenece una regex.
  2. Dominio y MX — una consulta DNS para confirmar que el dominio puede recibir correo siquiera. Consulta las guías de Node.js y Python para ver código funcional.
  3. Sondeo SMTP del buzón — la conversación de entrega que realmente confirma el buzón, más la detección de catch-all. Esto necesita un servidor de correo con una reputación de IP limpia y una limitación de tasa cuidadosa, por lo que la mayoría de equipos recurren a una API de verificación en lugar de construirlo. Demostrar que la persona es dueña de la dirección es otro trabajo, el de un correo de opt-in doble.

La comprobación de sintaxis que vale la pena conservar#

Para la capa 1, no te fabriques a mano el RFC 5322. La jugada pragmática es el input de correo HTML5 en el navegador (que aplica gratis el patrón del estándar vivo de la WHATWG) y una comprobación corta y permisiva en el servidor:

// Pragmatic: rejects fat-finger errors, accepts the addresses real
// mail servers actually deliver to. Not a deliverability check.
const SYNTAX = /^[^\s@."]+(?:\.[^\s@."]+)*@[^\s@.]+(?:\.[^\s@.]+)+$/;

function isPlausibleEmail(email) {
  return (
    email.length <= 254 &&      // RFC 5321 path limit
    email.indexOf("@") <= 64 && // local part limit
    SYNTAX.test(email)
  );
}

isPlausibleEmail("jane@example.com");             // true
isPlausibleEmail("jane+news@mail.example.co.uk"); // true
isPlausibleEmail("not-an-email");                 // false
isPlausibleEmail("a@@b.com");                     // false
isPlausibleEmail("a..b@x.com");                   // false: consecutive dots
isPlausibleEmail(".a@x.com");                     // false: leading dot
isPlausibleEmail("a.@x.com");                     // false: trailing dot

Úsala para dar retroalimentación instantánea mientras se escribe, nada más. Trata un aprobado como «vale la pena comprobarlo en serio», nunca como «válida».

El punto queda fuera de la clase de la parte local, así que solo puede ir entre caracteres. Eso rechaza los tres errores con puntos, acepta las cinco direcciones de la tabla de regex estrictas y mantiene el patrón rápido. La comprobación del navegador es una comodidad, no una barrera: cualquiera puede enviar datos directamente a tu endpoint, así que repite la comprobación en el servidor.

ReDoS: cuando la regex de correo es la vulnerabilidad#

Un patrón mal diseñado también puede bloquear tu servicio. Los motores integrados de JavaScript y Python hacen backtracking: cuando una coincidencia falla, prueban todas las demás formas en que el patrón podría dividir la entrada. Si un grupo repetido puede coincidir con los mismos caracteres que la parte anterior, el número de divisiones crece de forma exponencial.

Versiones anteriores de esta página recomendaban esa forma, [^\s@"]+(?:\.[^\s@"]+)*, en la que el punto encaja tanto en la clase como en el separador del grupo. Con una cadena de a. repetidos sin @, cada punto adicional duplicaba aproximadamente el tiempo de ejecución en nuestra propia prueba rápida en Node, y una entrada de menos de 60 caracteres bloqueaba el proceso durante segundos. Eso es ReDoS (CWE-1333). Si copiaste el patrón antiguo, sustitúyelo por el de arriba.

Tres soluciones:

  • Clases que no se solapan. Sacar el punto de las clases deja una sola forma de leer cualquier entrada, así que el patrón de arriba se ejecuta en tiempo lineal.
  • Un motor de tiempo lineal. El paquete regexp de Go lo garantiza, y los bindings de RE2 lo llevan a Node y Python.
  • Un parser en lugar de un patrón, como net/mail.ParseAddress de Go. Mantén Go actualizado: las versiones anteriores a 1.24.8 y 1.25.2 analizan con lentitud los literales de dominio muy largos.

Limitar la longitud no te salvará: esta forma se atasca muy por debajo de los 254 caracteres. Para detectar el fallo, mide el tiempo de una cadena que no coincida, como "a.".repeat(25) + "!": un patrón vulnerable tarda una fracción de segundo apreciable, y uno seguro responde al instante.

Comprobaciones de sintaxis por lenguaje#

La mayoría de los stacks incluyen una comprobación de sintaxis, así que rara vez necesitas un patrón propio. Cada guía cubre las tres capas; esta tabla muestra solo la capa 1.

StackComprobación de sintaxis
Node.jsLa regex de arriba
Expressexpress-validator isEmail()
Next.jszod z.string().email()
PythonLa regex de arriba
Djangovalidate_email o EmailField
FlaskWTForms Email()
PHPfilter_var() con FILTER_VALIDATE_EMAIL
Laravelemail:rfc,dns (sintaxis más una comprobación DNS de la ruta de correo)
Gonet/mail.ParseAddress
JavaJakarta Mail InternetAddress
Spring BootJakarta Bean Validation @Email
C#MailAddress.TryCreate
ASP.NET Core[EmailAddress]
RubyURI::MailTo::EMAIL_REGEXP
Railsformat con URI::MailTo::EMAIL_REGEXP

Las funciones integradas discrepan en los casos límite, como los nombres visibles (Jane <jane@example.com>); cada guía cubre las peculiaridades de su stack.

Recorrer el resto del camino#

Una vez que pasa la sintaxis, la verificación de verdad es un trabajo de red. Puedes construir las capas de DNS y SMTP tú mismo (las guías por lenguaje de arriba muestran hasta dónde puedes llegar), pero confirmar buzones en vivo a escala tropieza con el puerto 25 bloqueado en la mayoría de hosts, la reputación de IP y el greylisting, que es donde una API gestionada se gana su sitio. El endpoint POST /verify de Qualisend ejecuta toda la tubería y devuelve un veredicto de cuatro vías (deliverable | risky | undeliverable | unknown) con un código de motivo, de modo que tu código actúa en función de si el buzón existe y no de si la cadena tiene una @.

Preguntas frecuentes

01¿Existe una regex correcta para validar correos electrónicos?

No en el sentido que la gente querría. Existe una regex que implementa el RFC 5322, pero ocupa cientos o miles de caracteres, acepta formas exóticas que nunca querrías admitir y aun así no puede confirmar que la dirección sea entregable. Para uso práctico, un patrón corto y permisivo (o el input HTML5 type="email") para detectar erratas es la cantidad justa de regex; lo demás es un problema de DNS y SMTP.

02¿Por qué mi regex rechaza direcciones de correo válidas?

Porque los patrones estrictos incorporan suposiciones que las direcciones reales incumplen, como dominios de nivel superior de dos a cuatro letras (.photography tiene once) o la ausencia de signos más en la parte local. Una regex demasiado estricta es una causa habitual de registros perdidos. Sé permisivo con la sintaxis y verifica la entregabilidad por separado.

03¿Cuál es la longitud máxima de una dirección de correo?

254 caracteres. El RFC 5321 limita la parte anterior a la @ a 64 caracteres y el dominio a 255, y limita la ruta SMTP completa a 256, incluidos los corchetes angulares que rodean la dirección. Si se restan esos dos corchetes, quedan 254 para la dirección en sí. Las comprobaciones que permiten hasta 320 (64 + 1 + 255) son más laxas, pero inofensivas.

04¿La validación de correo de HTML5 comprueba si la dirección es real?

No. La validación type="email" del navegador es una comprobación de sintaxis: una versión más amable y estandarizada de la misma coincidencia de patrones. Detecta arrobas @ ausentes y errores evidentes en el input, pero nunca contacta con el servidor de correo, así que no puede decirte si el dominio o el buzón existen.

05¿Qué debería usar en lugar de regex para validar correos?

Hazlo por capas: una comprobación de sintaxis permisiva para dar retroalimentación instantánea, una consulta DNS/MX para descartar dominios muertos y un sondeo SMTP del buzón para confirmar la entrega. Las dos primeras puedes construirlas tú mismo; para la capa SMTP usa una API de verificación, ya que hacerlo de forma fiable requiere reputación de IP de envío y limitación de tasa que una regex nunca podría ofrecer.


¿Quieres ver la diferencia entre «sintaxis válida» y «se entregará de verdad»? El plan gratuito incluye 100 créditos de verificación que ejecutan la tubería completa (sintaxis, DNS y el sondeo SMTP del buzón), así que puedes ver cómo una dirección aprobada por regex vuelve como undeliverable. Sin cuenta, pega typo@gmial.com en el verificador de correo gratuito: todas las regex de esta página la aceptan, y el verificador sugiere gmail.com. La referencia de la API tiene ejemplos para copiar y pegar en siete lenguajes.

Tu reputación, protegida.

Limpia tu primera lista en minutos. 100 créditos gratis, sin tarjeta.

Empezar