WordPress “envió” el correo. Tu cliente no lo recibió. Soporte ahora reenvía capturas de pantalla de bandejas de entrada vacías, y el único artefacto concreto que tienes es una casilla de un plugin llamada “Use PHP mail()”.
Aquí está la verdad incómoda: la entrega de correo no es una funcionalidad de WordPress. Es un sistema distribuido con identidad, reputación, DNS, políticas y una docena de formas de fallar silenciosamente. La solución casi siempre es SMTP—pero no la versión de culto cargo “instala un plugin y reza”. La solución es una configuración SMTP que puedas observar, probar y operar.
Guía rápida de diagnóstico
Si estás de guardia, no tienes tiempo para redescubrir SMTP. Necesitas encontrar el cuello de botella rápido: ¿WordPress? ¿PHP? ¿MTA local? ¿red? ¿relay remoto? ¿política DNS? ¿filtrado del destinatario? Usa esta secuencia.
Primero: confirma si WordPress siquiera intenta enviar
- Dispara un correo conocido: restablecimiento de contraseña para un usuario de prueba, correo de pedido de WooCommerce o un envío de formulario que registre un evento.
- Revisa logs de la aplicación: logs del plugin (si tu plugin SMTP los soporta), logs del servidor web para la petición y el log de depuración de WordPress si está habilitado.
- Decisión: Si no hay intento, tienes un problema de aplicación/configuración. Si hay intento, continúa.
Segundo: identifica la ruta de envío
- ¿Es PHP mail() hacia un MTA local? Eso significa “WordPress entregó un mensaje al servidor”. No dice nada sobre la entrega real.
- ¿Es SMTP directo a un relay? Mejor: puedes autenticar, registrar y rastrear fallos.
- Decisión: Si no puedes nombrar la ruta en una frase, no tienes un sistema—tienes sensaciones.
Tercero: localiza el primer error duradero
- ¿La cola del MTA local crece? Revisa la cola y los logs de Postfix/Exim.
- ¿SMTP remoto rechaza? Necesitas el código de error remoto (5xx/4xx) y la razón.
- Aceptado pero no recibido? Entregabilidad y políticas: SPF/DKIM/DMARC alineamiento, reputación, contenido, limitación de tasa o filtrado por parte del destinatario.
- Decisión: No cambies cinco cosas a la vez. Captura el primer error sólido y luego arregla la causa detrás de él.
Idea parafraseada (atribuida): Haz visible la falla; la fiabilidad empieza por observar lo que el sistema realmente hace
— Charity Majors (idea parafraseada).
Qué falla realmente cuando WordPress no puede enviar correos
“WordPress no envía correos” suele ser uno de estos casos:
- No hay MTA o el MTA local está roto. Muchas imágenes de VPS modernas no incluyen un agente de transferencia de correo configurado. PHP puede llamar a
sendmail, pero no hay nada sensato detrás. - El proveedor bloquea el SMTP saliente. Algunos hosts bloquean el puerto 25 o limitan el correo desde rangos IP compartidos. Los proveedores en la nube hacen esto para reducir el abuso.
- La autenticación SMTP falla. Usuario incorrecto, contraseña equivocada, puerto incorrecto, modo de cifrado erróneo, identidad “From” incorrecta o ajustes de tenant equivocados (hola, Microsoft 365).
- Falta o desalineación de identidad DNS. SPF demasiado estricto, DKIM no configurado, DMARC en modo de aplicación y falla de alineamiento. El correo es rechazado o silenciosamente enviado a carpeta bulk.
- Problemas de reputación y políticas. Dominio/IP nuevos que envían correos transaccionales parecen sospechosos. Los sistemas receptores no les importa que sean “solo restablecimientos de contraseña”. Les importan las señales.
- El contenido dispara filtros. Formularios que envían contenido generado por usuarios pueden parecer phishing, o incluir URLs en listas negras.
- Problemas de tiempo y TLS. La hora del sistema incorrecta rompe la validación TLS. Cifrados antiguos rompen puntos SMTP modernos. “Funciona en mi portátil” porque tu portátil no es el servidor.
Broma #1: La entregabilidad del correo es como un portero de discoteca: puedes estar en la lista y aun así no entrar porque “pareces sospechoso”.
En producción, trato el correo de WordPress como una canalización con puntos de control:
- Punto de control de la app: WordPress llama a wp_mail().
- Punto de control de transporte: el plugin entrega a SMTP o PHP mail() entrega al MTA local.
- Punto de control del relay: el relay SMTP acepta (o rechaza) el mensaje.
- Punto de control del destinatario: el SMTP del destinatario acepta (o rechaza) desde el relay.
- Punto de control de bandeja: el filtrado y la política deciden dónde aterriza, o si se pone en cuarentena.
Tu trabajo es encontrar el primer punto de control donde la realidad diverge de la expectativa. Todo lo que viene después es ruido aguas abajo.
Datos interesantes (y por qué siguen importando)
- SMTP es anterior a la web. La especificación core de SMTP precede al hosting web moderno, lo que explica por qué asume mucha confianza y añadió autenticación después.
- SPF fue diseñado para detener remitentes de sobreescritura del envelope, no las cabeceras “From:”. Muchos esperan que SPF valide lo que ven los usuarios. No lo hace—el alineamiento mediante DMARC es lo que lo ata todo.
- DKIM firma el cuerpo del mensaje y cabeceras seleccionadas. Eso significa que algunos relays “útiles” que reescriben contenido pueden romper firmas y hundir la entrega.
- DMARC existe porque SPF y DKIM solos no eran suficientes. DMARC añade política e informes, y formaliza el alineamiento para que los receptores puedan hacer cumplir.
- El greylisting sigue existiendo. Algunos destinatarios rechazan temporalmente a remitentes primerizos (un 4xx). Buenas MTAs reintentan; implementaciones ingenuas declaran fallo y abandonan.
- Las IPs de hosting compartido suelen heredar mala reputación. Tu sitio puede comportarse bien, pero tu vecino de IP puede ser un cañón de newsletters imparable.
- El puerto 25 suele estar bloqueado por proveedores en la nube. No porque te odien—porque el spam es una externalidad y ellos pagan por la reputación y la respuesta a abuso.
- El correo transaccional y el de marketing tienen expectativas diferentes. Los restablecimientos de contraseña necesitan entrega rápida y alta confianza; el correo masivo necesita warm-up y cumplimiento estricto. Mezclarlos perjudica a ambos.
- La dirección “From” importa más de lo que se piensa. Muchos receptores aplican reputación de dominio a nivel de la cabecera From, no sólo al IP remitente.
Elige tu arquitectura SMTP (y evita las malas tentaciones)
Opción A: Usar un servicio relay SMTP dedicado (recomendado)
Esta es la respuesta madura para la mayoría de los sitios WordPress que importan. Tu host de WordPress ejecuta la app. Un relay dedicado gestiona entregabilidad, reintentos, procesamiento de rebotes, bucles de feedback y reputación de IP.
Pros: mejor entregabilidad, logs reales, comportamiento de throttling predecible, soporte más fácil para autenticación de dominio. Contras: cuesta dinero, requiere trabajo en DNS, credenciales que gestionar.
Elige esto cuando: envíes restablecimientos de contraseña, confirmaciones de pedido, correos de membresía o cualquier cosa de la que los usuarios se quejarían si falla.
Opción B: Usar el SMTP del proveedor de correo corporativo (a veces aceptable)
Gmail/Google Workspace o Microsoft 365 pueden funcionar para correo transaccional de bajo volumen, pero espera limitaciones: límites de tasa, restricciones sobre el “from”, cambios de OAuth vs basic auth, políticas del tenant y sorpresas ocasionales.
Pros: ya lo pagas, consola de administración conocida. Contras: límites, fricción en auditoría y es fácil configurar identidades mal y romper DMARC.
Opción C: Ejecutar Postfix en el servidor y entregar directamente (rara vez vale la pena)
Sí, puedes ejecutar tu propio MTA saliente y enviar directamente a los MX de destinatarios. Si estás leyendo esto porque el correo de WordPress es poco fiable, probablemente no quieras también convertirte en ingeniero de reputación de correo.
Pros: control total. Contras: gestión de reputación, listas de bloqueo, reverse DNS, manejo de abuso, ajuste constante. Además: te echarán la culpa por spam que no enviaste.
El mal por defecto: PHP mail() en el vacío
PHP mail() no es “incorrecto”, es simplemente el transporte menos observable. Es una entrega a lo que esté configurado en sendmail_path. En hosting compartido puede funcionar. En entornos gestionados modernos a menudo apunta a nada o a un relay local sin trabajo de entregabilidad.
Tareas prácticas: comandos, salidas, decisiones (12+)
Estas tareas están diseñadas para ejecutarse en el host de WordPress (o el host del contenedor) con acceso a shell. Cada una incluye: comando, salida de ejemplo, qué significa y la decisión que tomas.
Task 1: Confirmar que el host de WordPress puede resolver DNS correctamente
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 1.1.1.1
DNS Servers: 1.1.1.1 8.8.8.8
Significado: La resolución DNS está configurada y apunta a resolvers alcanzables.
Decisión: Si DNS falla o apunta a un resolver interno que no puede resolver registros públicos, arregla DNS primero. Resolver SMTP sin DNS es performance art.
Task 2: Comprobar si los puertos SMTP salientes son accesibles
cr0x@server:~$ nc -vz smtp.mailprovider.example 587
Connection to smtp.mailprovider.example 587 port [tcp/submission] succeeded!
Significado: La ruta de red al relay en el puerto 587 (submission) está abierta.
Decisión: Si esto falla, tratas con reglas de firewall, controles de egreso de la nube o restricciones del proveedor. Usa 587/465 con autenticación; no pelees contra bloqueos de 25 a menos que disfrutes tickets de abuso.
Task 3: Verificar la hora del sistema (TLS depende de ella)
cr0x@server:~$ timedatectl
Local time: Sat 2025-12-27 13:05:41 UTC
Universal time: Sat 2025-12-27 13:05:41 UTC
RTC time: Sat 2025-12-27 13:05:41
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Significado: El reloj está sincronizado; la validación de certificados TLS no fallará porque el sistema crea que es 1970.
Decisión: Si no está sincronizado, arregla NTP. Fallos TLS aleatorios te harán perder la tarde.
Task 4: Identificar si existe un MTA local
cr0x@server:~$ command -v sendmail; systemctl status postfix 2>/dev/null | head
/usr/sbin/sendmail
Unit postfix.service could not be found.
Significado: Existe un binario sendmail (quizá de msmtp o nullmailer), pero Postfix no está instalado.
Decisión: Si dependes de PHP mail(), necesitas saber qué es realmente /usr/sbin/sendmail. Si falta o está inerte, cambia a SMTP por plugin o instala/configura un MTA apropiado.
Task 5: Ver qué piensa PHP que es “sendmail”
cr0x@server:~$ php -i | grep -E '^sendmail_path|^mail\.force_extra_parameters'
sendmail_path => /usr/sbin/sendmail -t -i => /usr/sbin/sendmail -t -i
mail.force_extra_parameters => no value => no value
Significado: PHP llamará a /usr/sbin/sendmail -t -i.
Decisión: Si no operas intencionadamente un MTA local, deja de usar esta ruta. Por defecto no se registra y falla de maneras creativas.
Task 6: Si Postfix existe, inspecciona la cola de correo
cr0x@server:~$ mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
3F2A91234A 2213 Sat Dec 27 12:58:02 wordpress@example.com
user@gmail.com
(connect to gmail-smtp-in.l.google.com[142.250.102.27]:25: Connection timed out)
-- 1 Kbytes in 1 Request.
Significado: Mensajes están en cola y no pueden alcanzar el MX del destinatario en el puerto 25 (timeout).
Decisión: Deja de intentar entregar directo-a-MX desde este host. Usa un relay autenticado en 587/465. La cola te está diciendo que la ruta de red está bloqueada.
Task 7: Leer logs de correo para errores SMTP (ejemplo Postfix)
cr0x@server:~$ sudo tail -n 30 /var/log/mail.log
Dec 27 12:58:02 server postfix/smtp[21877]: connect to gmail-smtp-in.l.google.com[142.250.102.27]:25: Connection timed out
Dec 27 12:58:32 server postfix/smtp[21877]: connect to gmail-smtp-in.l.google.com[2607:f8b0:400e:c06::1b]:25: Network is unreachable
Dec 27 12:59:02 server postfix/qmgr[901]: 3F2A91234A: from=<wordpress@example.com>, size=2213, nrcpt=1 (queue active)
Significado: Timeouts consistentes e IPv6 inalcanzable. Esto no es un bug de WordPress.
Decisión: Configura Postfix para reenviar vía un smarthost en 587, o desactiva IPv6 si está mal enrutado. Mejor: evita el MTA local y usa el plugin SMTP directo a un relay.
Task 8: Probar autenticación SMTP y TLS con OpenSSL
cr0x@server:~$ openssl s_client -starttls smtp -connect smtp.mailprovider.example:587 -servername smtp.mailprovider.example -crlf
CONNECTED(00000003)
depth=2 C=US O=Example CA CN=Example Root CA
verify return:1
depth=1 C=US O=Example CA CN=Example Issuing CA
verify return:1
depth=0 CN=smtp.mailprovider.example
verify return:1
---
250 STARTTLS
250 AUTH PLAIN LOGIN
250 PIPELINING
250 SIZE 10485760
Significado: La negociación TLS funciona; el servidor anuncia mecanismos AUTH.
Decisión: Si la verificación del certificado falla, arregla el CA bundle o un proxy interceptador. Si STARTTLS no se ofrece, estás en el puerto equivocado o el proveedor requiere TLS implícito (465).
Task 9: Validar presencia del registro SPF para tu dominio remitente
cr0x@server:~$ dig +short TXT example.com | grep -i spf
"v=spf1 include:_spf.mailprovider.example -all"
Significado: El dominio tiene un registro SPF autorizando tu relay.
Decisión: Si falta, añádelo. Si termina en -all y no incluyes el relay, los receptores te rechazarán o enviarán a spam. Si hay múltiples registros SPF, arréglalo también (ver Task 10).
Task 10: Detectar múltiples registros SPF (error común autoinducido)
cr0x@server:~$ dig +short TXT example.com | grep -i "v=spf1" | wc -l
2
Significado: Existen dos registros SPF. Los receptores tratan eso como error permanente (PermError) y SPF falla efectivamente.
Decisión: Fusiona los mecanismos SPF en un solo registro. No publiques múltiples TXT con v=spf1.
Task 11: Confirmar que existen registros DKIM (basados en selector)
cr0x@server:~$ dig +short TXT s1._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
Significado: La clave pública DKIM está presente para el selector s1.
Decisión: Si falta, habilita DKIM en tu proveedor relay y publica el TXT exactamente como te lo dan. DKIM ya no es opcional para entrega consistente.
Task 12: Confirmar política DMARC y expectativas de alineamiento
cr0x@server:~$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; adkim=s; aspf=s; rua=mailto:dmarc@example.com"
Significado: DMARC está aplicando quarantine con alineamiento estricto para DKIM y SPF.
Decisión: El alineamiento estricto significa que tu cabecera From: visible debe coincidir con los dominios autenticados. Configura el “From Email” de WordPress y la identidad del relay para alinear, o relaja el alineamiento si entiendes las implicaciones.
Task 13: Comprobar reverse DNS (PTR) de tu IP remitente (si envías directo)
cr0x@server:~$ dig +short -x 203.0.113.10
mail.example.com.
Significado: Existe PTR. Muchos receptores desconfían de IPs sin rDNS.
Decisión: Si entregas directamente, arregla PTR con tu ISP/proveedor cloud. Si retransmites vía un proveedor SMTP, esto importa menos para tu host y más para las IPs del relay.
Task 14: Observar errores de WordPress/PHP alrededor del envío (PHP-FPM)
cr0x@server:~$ sudo tail -n 40 /var/log/php8.2-fpm.log
[27-Dec-2025 12:57:51] WARNING: [pool www] child 18234 said into stderr: "PHP Warning: fsockopen(): Unable to connect to smtp.mailprovider.example:587 (Connection timed out) in /var/www/html/wp-includes/PHPMailer/SMTP.php on line 214"
[27-Dec-2025 12:57:51] WARNING: [pool www] child 18234 said into stderr: "SMTP connect() failed."
Significado: La aplicación intentó SMTP pero expiró—ruta de red o firewall.
Decisión: Arregla firewall de egreso/security groups, NAT o restricciones del proveedor de hosting. No sigas tocando ajustes del plugin cuando el handshake TCP nunca ocurre.
Task 15: Prueba SMTP end-to-end rápida usando swaks (si está instalado)
cr0x@server:~$ swaks --to user@gmail.com --from wordpress@example.com --server smtp.mailprovider.example --port 587 --auth LOGIN --auth-user wordpress@example.com --auth-password 'REDACTED' --tls
=== Trying smtp.mailprovider.example:587...
=== Connected to smtp.mailprovider.example.
<= 220 smtp.mailprovider.example ESMTP ready
=> EHLO server
<= 250-AUTH PLAIN LOGIN
=> AUTH LOGIN
<= 235 2.0.0 Authentication successful
=> MAIL FROM:<wordpress@example.com>
<= 250 2.1.0 Ok
=> RCPT TO:<user@gmail.com>
<= 250 2.1.5 Ok
=> DATA
<= 354 End data with <CR><LF>.<CR><LF>
=> .
<= 250 2.0.0 Accepted for delivery
=== Connection closed with remote host.
Significado: El relay SMTP aceptó el mensaje. Ahora estás en territorio de entregabilidad, no de transporte.
Decisión: Si fue aceptado pero no recibido, inspecciona logs del relay, revisa carpetas de spam/quarantine, verifica SPF/DKIM/DMARC y asegúrate de que el “From” coincida con tu dominio autenticado.
Configuración SMTP en WordPress que resiste producción
WordPress usa PHPMailer internamente. El modo clásico de fallo es que WordPress está configurado para “enviar” mail pero el transporte está o ausente (sin MTA) o sin confianza (IP compartida sin autenticación). SMTP soluciona ambos haciendo el envío explícito.
Elige un plugin SMTP—y trátalo como infraestructura
No voy a discutir marcas. Elige un plugin SMTP reputado que:
- soporte SMTP autenticado con TLS
- pueda registrar intentos de envío y errores
- te permita fijar un From consistente nombre/email
- soporte OAuth si tu proveedor lo exige
Reglas de configuración que previenen los desastres habituales
- Usa el puerto 587 con STARTTLS salvo que tu proveedor requiera explícitamente 465 (TLS implícito). El puerto 25 es para servidor-a-servidor y suele estar bloqueado.
- Configura From Email a un buzón real o remitente autorizado en el mismo dominio que autenticas. No uses
wordpress@localhostono-reply@tudominiosalvo que tu relay lo permita y tu DNS esté alineado. - Forzar From Email y From Name para correo transaccional. Plugins y temas adoran sobreescribir cabeceras; eso rompe el alineamiento y crea problemas de entregabilidad “aleatorios”.
- No uses credenciales de buzón personal para un sitio web. Usa una cuenta de servicio o clave API del relay. Rótala. Guárdala en tu gestor de secretos si tienes uno.
- Activa logs del plugin si están disponibles, al menos durante el despliegue. Querrás timestamps y códigos de error SMTP.
- Separa transaccional de marketing si el volumen crece. Aunque sea el mismo proveedor, usa subdominios o identidades de envío separadas para que uno no contamine al otro.
Identidad: la dirección “From” no es un tema estético
Para correo alineado con DMARC, la cabecera visible From: debe alinearse con ya sea:
- Dominio alineado por SPF (el remitente envelope / return-path), o
- Dominio d= firmado por DKIM (el dominio que firma el mensaje)
Si autenticas SMTP como wordpress@example.com pero tu plugin pone From como wordpress@otro-dominio, DMARC puede fallar incluso si la autenticación SMTP tiene éxito. Por eso “SMTP funciona pero los correos siguen desapareciendo”.
Broma #2: La cabecera “From” es como una chapa en una conferencia—si no coincide con tu registro, seguridad se interesa.
DNS y autenticación de dominio: SPF, DKIM, DMARC
SMTP saca el correo por la puerta. La autenticación hace que lo acepten—y lo traten como ciudadano responsable una vez que llega. En 2025, debes asumir que los buzones grandes desconfían por defecto.
SPF: autoriza remitentes, no lo compliques
SPF es un registro TXT que dice “estos hosts/IPs pueden enviar correo por mi dominio”. Los receptores comparan la IP conectante con esa política.
Reglas para mantener SPF sensato:
- Publica exactamente un registro SPF por dominio.
- Prefiere mecanismos
include:para tu proveedor relay; evita listar docenas de IPs a menos que las controles. - Vigila el límite de búsquedas DNS (10). Demasiados includes pueden causar SPF PermError.
- Decide la política:
~all(softfail) durante migración;-all(fail) cuando estés seguro.
DKIM: integridad e identidad de dominio
DKIM firma el correo saliente con una clave privada; los destinatarios verifican con tu clave pública publicada. Esto prueba que el mensaje no fue modificado en tránsito y lo ata a un dominio.
Notas operativas:
- Usa claves de 2048 bits donde esté soportado.
- Rota selectores periódicamente (ej.,
s1,s2). Mantén selectores antiguos durante la superposición. - Cuidado con plugins o relays que reescriben HTML o añaden pies de página; pueden romper DKIM a menos que la firma ocurra después de la reescritura (los proveedores suelen gestionar esto correctamente).
DMARC: política, alineamiento y la diferencia entre “enviado” y “confiable”
DMARC le dice a los receptores qué hacer si SPF y DKIM no se alinean con el dominio visible From, y dónde enviar informes.
Progresión práctica de DMARC:
- Empieza con p=none para medir sin romper correo.
- Pasa a p=quarantine una vez que arregles alineamiento y remitentes no autorizados.
- Usa p=reject cuando estés seguro de no bloquear remitentes legítimos (y hayas inventariado todos los sistemas que envían como tu dominio).
Trampas de alineamiento específicas de WordPress
- Plugins de formularios a veces ponen From como el email del visitante. Eso es una falla DMARC esperando ocurrir. Usa Reply-To para el visitante en su lugar.
- Instalaciones Multisite pueden variar dominio From por sitio. Si no puedes autenticar todos, tendrás entrega inconsistente.
- Herramientas de marketing de terceros podrían también enviar desde el dominio raíz. Coordina SPF/DKIM/DMARC o separa en subdominios.
Realidad de la entregabilidad: reputación, límites y contenido
Una vez que SMTP acepta el mensaje, entras en la tierra de heurísticas, sistemas de reputación y políticas anti-abuso. No es personal. Es matemática.
Qué significa realmente “aceptado para entrega”
Cuando tu relay dice “250 Accepted”, significa que el relay aceptó la responsabilidad de intentar la entrega. No garantiza la colocación en la bandeja de entrada. Ni siquiera garantiza que el destinatario lo haya aceptado—solo que el relay lo intentará.
Reputación: tu dominio y comportamiento de envío
Los proveedores de buzón construyen reputación a partir de señales como:
- autenticación consistente (alineamiento SPF/DKIM/DMARC)
- bajas tasas de rebote
- bajas tasas de queja (usuarios marcando como “spam”)
- patrones de volumen consistentes (picos súbitos parecen compromiso)
- calidad del contenido y reputación de enlaces
Límites de tasa y errores transitorios
Muchos fallos SMTP son 4xx deferrals temporales: “intenta más tarde”. Un buen relay reintenta con backoff. Una mala configuración lo marca como fallado instantáneamente y nunca lo notas excepto por quejas de clientes.
Contenido: los correos de WordPress pueden ser carnaza para filtros
Disparadores comunes:
- formularios que permiten contenido arbitrario del usuario, incluyendo URLs sospechosas
- mensajes con mala proporción texto/HTML o codificaciones raras
- líneas de asunto que parecen phishing (“Urgente: Verificación de cuenta”)
- enviar “From” desde un dominio sin alineación web (dominio nuevo, sin historial)
Si tu mensaje incluye contenido generado por usuarios, trátalo como entrada no confiable. Sanitízalo. Limita enlaces. Considera enviar una notificación mínima con un enlace para ver el mensaje dentro de tu app web autenticada.
Tres microhistorias corporativas desde el campo
Microhistoria #1: El incidente causado por una suposición equivocada
La configuración parecía normal: WordPress en un VPS gestionado, un plugin de formulario de contacto y una dirección From configurada como support@company.example. El equipo asumió que porque el sitio usaba el dominio de la empresa, la autenticación de correo “ya debía estar bien”. Habían configurado SPF años atrás para su plataforma de newsletters y lo dieron por hecho.
Entonces sucedió un cambio silencioso: la política DMARC pasó de p=none a p=quarantine tras una revisión de seguridad. Nadie le dijo al equipo web, porque claro, nadie le dijo al equipo web. De repente, los correos del formulario de contacto dejaron de aparecer para un subconjunto de destinatarios—principalmente bandejas corporativas con filtrado más estricto.
La primera respuesta fue culpar a WordPress. La segunda fue reinstalar el plugin. La tercera fue “usar PHP mail()”. Nada de eso importó. El problema real: el plugin del formulario ponía el email del visitante como cabecera From (para que las respuestas quedaran bonitas). Eso significó que el alineamiento DMARC fallaba para cada mensaje donde el visitante usó un dominio con p=reject (y hay muchos).
La solución fue aburrida: mantener From como support@company.example, poner Reply-To al visitante. Añadir firma DKIM vía un relay adecuado. El incidente terminó no con un parche heroico, sino con una cabecera de correo que dejó de mentir.
Microhistoria #2: La optimización que salió mal
Otra organización tenía una tienda WooCommerce de alto tráfico. Pagaban por un relay y decidieron “optimizar” enviando restablecimientos de contraseña y confirmaciones de pedido a través de su propio Postfix para ahorrar unos dólares. Tenían una IP, un servidor y correo es “solo SMTP”, ¿no?
Funcionó unas dos semanas. Luego la entregabilidad se degradó. Algunos proveedores comenzaron a diferir con límites 4xx. Otros pusieron todo en carpeta bulk. La cola de soporte se llenó con “No recibí mi recibo.” Peor: los correos de restablecimiento de contraseña desaparecían intermitentemente, provocando bloqueos de cuentas y contracargos porque los clientes no podían acceder al estado de su pedido.
El equipo intentó tunear Postfix, cambiar nombres HELO y enviar desde otro dominio. Perseguían síntomas. El problema real era reputación y comportamiento: una IP nueva con patrones de volumen en picos, sin confianza establecida y rebotes ocasionales por direcciones mal tecleadas.
Regresaron al proveedor relay para el correo transaccional y mantuvieron Postfix solo como punto de envío local hacia el relay (smarthost), no como emisor directo a MX. La “optimización” ahorró dinero hasta que dejó de hacerlo. Lo que salió mal no fue la complejidad técnica—fue subestimar cuánto les importa a los receptores el historial del remitente.
Microhistoria #3: La práctica aburrida pero correcta que salvó el día
Una empresa SaaS usaba múltiples instancias de WordPress para sitios de marketing y portales de documentación. Ya habían sufrido antes, así que estandarizaron el envío: cada WordPress usaba el mismo proveedor relay, dominio de envío separado (mail.company.example) y forzaban From. También centralizaron logs SMTP.
Un lunes, los correos de restablecimiento de contraseña se ralentizaron. No se detuvieron—se ralentizaron. Soporte detectó un patrón: usuarios de Gmail recibían, algunos dominios corporativos no. El SRE de guardia no tocó WordPress. Miró los logs del relay y vio deferrals 4xx crecientes de una familia de dominios receptores específicos.
Porque tenían informes DMARC y firmas DKIM consistentes, pudieron descartar autenticación rápidamente. Los deferrals eran limitaciones por parte del destinatario debido a un incidente en su lado. Su relay reintentó automáticamente con backoff y la entrega se recuperó en horas.
La maniobra salvadora no fue ingeniosa. Fue que habían construido observabilidad y consistencia en la infraestructura “aburrida” de correo, así el incidente fue una actualización de estado, no un simulacro de incendio.
Errores comunes: síntoma → causa raíz → solución
1) “WordPress dice enviado, pero nada llega”
Causa raíz: Usar PHP mail() sin un MTA funcional, o con un MTA local que no puede entregar (puerto 25 bloqueado, sin relay, cola atascada).
Solución: Configura SMTP autenticado a un relay en 587/465. Si debes usar un MTA local, configúralo para reenviar vía smarthost y monitorea la cola.
2) “SMTP funciona en el correo de prueba del plugin, pero los correos de formularios fallan”
Causa raíz: El plugin del formulario pone From al email del visitante; el alineamiento DMARC falla o el relay rechaza suplantaciones.
Solución: Pone From a tu dominio (alineado con DKIM/SPF). Pon el email del visitante en Reply-To. La mayoría de plugins de formularios tiene una opción para esto.
3) “Autenticación falló” o “535 5.7.3 Authentication unsuccessful”
Causa raíz: Credenciales incorrectas, método de auth equivocado, basic auth deshabilitada o el proveedor requiere app password/OAuth.
Solución: Usa el método aprobado por el proveedor: app password, credencial de relay, o OAuth. Confirma puerto/cifrado. Deja de reciclar contraseñas de buzones personales.
4) “Connection timed out” al host SMTP
Causa raíz: Firewall de egreso, restricciones de security group, proveedor bloqueando SMTP saliente, DNS mal o ruta IPv6 rota.
Solución: Prueba con nc y openssl s_client. Permite egreso al relay en 587/465. Desactiva IPv6 rota o arregla el enrutamiento.
5) Correos van a spam en proveedores grandes
Causa raíz: DKIM faltante o fallando, SPF PermError (múltiples registros SPF), DMARC mal alineado o mala reputación.
Solución: Publica SPF correcto (registro único), habilita DKIM, añade DMARC (empieza con p=none), asegúrate que From se alinee con el dominio autenticado. Considera un relay reputado y un warm-up gradual.
6) “Algunos destinatarios reciben, otros nunca”
Causa raíz: Filtrado específico del destinatario, greylisting, limitación de tasa o bloqueo del IP/dominio remitente.
Solución: Usa un relay con retry/backoff y logs. Revisa eventos del relay para deferrals y rebotes. No asumas comportamiento uniforme entre destinatarios.
7) Correos de restablecimiento fallan después de una migración del sitio
Causa raíz: Reputación del IP del nuevo host, registros DNS faltantes en la nueva zona DNS o envío desde un dominio no autorizado por el nuevo relay.
Solución: Re-verifica SPF/DKIM/DMARC en la zona DNS activa. Usa las mismas credenciales y dominio de envío. Confirma que la dirección From no haya vuelto a un valor por defecto.
8) “Funcionaba hasta que activamos caching/CDN/plugin de seguridad”
Causa raíz: No es generalmente la caché. Suele ser un cambio coincidente: actualización de plugin, credenciales rotadas, política del proveedor cambiada, firewall de salida más estricto, o wp-cron detenido y notificaciones en cola que no se disparan.
Solución: Verifica wp-cron/cron real, conectividad SMTP y logs del plugin. Correlaciona timestamps con despliegues y cambios de credenciales.
Listas de verificación / plan paso a paso
Paso a paso: de “sin correo” a “entregado con fiabilidad”
- Decide la arquitectura: usa un relay SMTP dedicado para correo transaccional.
- Elige la identidad de envío: p. ej.,
no-reply@example.comosupport@example.com—pero que sea real y alineada. - Configura el plugin SMTP en WordPress: host, puerto 587, STARTTLS, auth habilitado, forzar From.
- Publica SPF: registro único incluyendo al proveedor relay.
- Publica DKIM: registros selector(es) proporcionados por el relay.
- Publica DMARC: empieza con
p=nonecon reportes, luego avanza a enforcement cuando esté estable. - Ejecuta pruebas de conectividad desde el servidor:
nc+openssl s_clienthacia el relay. - Envía un correo de prueba: confirma que el relay lo acepta y el destinatario lo recibe.
- Arregla alineamiento para formularios: From = tu dominio, Reply-To = visitante.
- Activa logging: logs del plugin + logs del relay; consérvalos lo suficiente para depurar incidentes.
- Configura monitoreo: alerta en fallos sostenidos de envío, crecimiento de cola (si aplica) y picos de rebotes.
- Documenta la “configuración buena”: ubicación de credenciales, registros DNS y la razón de por qué existe este relay.
Checklist operativo: qué revisar durante un incidente
- ¿El servidor puede alcanzar el relay en 587/465?
- ¿Han rotado o expirado las credenciales?
- ¿Hubo actualizaciones recientes de WordPress/plugin?
- ¿Cambios DNS recientes (SPF/DKIM/DMARC) o cortes de zona?
- Logs del relay: rechazos (5xx) vs deferrals (4xx) vs aceptados.
- ¿Afectan solo dominios específicos?
Reglas estrictas (porque te vas a sentir tentado)
- No envíes mail de formularios con el visitante como From. Usa Reply-To.
- No confíes en PHP mail() en entornos que no controlas. Si no puedes leer logs de correo, no tienes un sistema.
- No publiques múltiples registros SPF. Jamás.
- No uses credenciales de buzón compartido en producción. Crea una identidad de servicio.
Preguntas frecuentes
1) ¿Por qué WordPress “funciona” en un host pero no en otro?
Porque PHP mail() depende del MTA y las políticas de red del host. Un host tiene un relay configurado; otro no tiene nada detrás de /usr/sbin/sendmail, o SMTP saliente está bloqueado.
2) ¿Debo usar el puerto 465 o 587?
Usa 587 con STARTTLS salvo que tu proveedor diga explícitamente 465. Ambos pueden ser seguros; 587 es el default moderno de submission y suele comportarse de forma predecible a través de firewalls.
3) Mi prueba SMTP dice “éxito”, pero los correos aún no aparecen. ¿Ahora qué?
Eso es entregabilidad o filtrado del destinatario. Verifica alineamiento SPF/DKIM/DMARC, revisa logs de evento del relay por rebotes/deferrals y prueba enviando a múltiples proveedores. También revisa spam/cuarentena.
4) ¿Puedo usar mis credenciales de Gmail o Microsoft 365?
Puedes, pero es frágil. Los proveedores cambian reglas de auth, exigen MFA y limitan throughput. Prefiere un relay dedicado o una contraseña de aplicación/flujo OAuth con cuenta de servicio soportada.
5) ¿Qué dirección “From” debería usar WooCommerce?
Usa una dirección en tu dominio que autentiques (p. ej., orders@example.com). Forzala en tu plugin SMTP para que las plantillas y extensiones no la sobreescriban y causen desalineamiento.
6) ¿Por qué los correos de formulario fallan a menudo solo para ciertos remitentes?
Si el formulario pone From como el visitante, las políticas DMARC del dominio del visitante pueden provocar rechazo o colocación en spam. Muchos dominios publican DMARC estricto para detener este tipo de suplantación.
7) ¿Necesito DKIM si SPF está correcto?
Sí, si quieres entrega consistente. SPF puede romperse con reenvíos y no firma contenido. DKIM añade integridad y suele mejorar la confianza. DMARC funciona mejor cuando ambos están presentes.
8) ¿Cuál es la forma más rápida de saber si es un bloqueo de red?
Ejecuta nc -vz relay 587 y openssl s_client -starttls smtp desde el host de WordPress. Los timeouts y mensajes de “no route” ganan a adivinar.
9) ¿Alguna vez vale la pena ejecutar mi propio Postfix para saliente?
A veces: si tienes un equipo de correo, espacio IP estable, control de reverse DNS y el apetito para gestionar reputación y abuso. Para la mayoría de sitios WordPress, retransmitir por un proveedor es más barato que tu tiempo.
10) ¿Cómo evito que los correos vayan a spam sin cambiar contenido?
Empieza con alineamiento de autenticación (SPF/DKIM/DMARC), luego consistencia de envío (volúmenes estables) y reputación (usa un relay confiable). Los cambios de contenido ayudan, pero la identidad es la base.
Próximos pasos que puedes hacer hoy
Si el correo de WordPress falla, no discutas con él. Instruméntalo y dale un transporte real.
- Pásate de PHP mail() a menos que operes intencionadamente un MTA local con logs y ruta de relay.
- Configura SMTP autenticado a un relay dedicado en 587/465 y prueba conectividad desde el host.
- Publica y verifica SPF/DKIM/DMARC y asegúrate de que la dirección From de WordPress se alinee con lo que autentica tu relay.
- Arregla plugins de formularios para que el email del visitante vaya en Reply-To, no en From.
- Mantén logs (plugin + relay) y úsalos para distinguir fallos de transporte de problemas de entregabilidad.
Haz eso, y “WordPress no envía correos” dejará de ser un misterio recurrente y pasará a ser un subsistema aburrido y monitorizable. Aburrido es bueno. Aburrido es como duermes.