La página principal carga. El administrador funciona. Pero cada entrada devuelve un 404. Eso no es “WordPress siendo WordPress.” Es la capa de enrutamiento: las reglas de rewrite de WordPress, la configuración del servidor web, cachés o redirecciones—discutiendo qué significa una URL.
Y sí, es un incidente en producción. Las entradas generan ingresos, clientes potenciales y credibilidad. Arreglarlo rápido es fácil. Arreglarlo correctamente—sin quemar señales SEO y dejando un rastro de URLs rotas—es lo que separa un parche rápido de un postmortem de incidente.
Plan rápido de diagnóstico
Si solo tienes 15 minutos antes de que alguien “simplemente vuelva a cambiar los permalinks” en pánico, haz esto en orden. Buscas la ruta más corta hacia la certeza.
Primero: confirma qué tipo de 404 estás recibiendo
- 404 del servidor (Nginx/Apache): WordPress nunca se ejecutó. Arregla el enrutamiento del servidor.
- 404 de WordPress (página 404 del theme): PHP se ejecutó, WordPress no pudo resolver la petición a una entrada. Arregla reglas de rewrite, estructura de permalinks, query vars o slugs en la base de datos.
- 404 en caché del CDN/WAF: El origen puede estar arreglado pero los usuarios siguen viendo 404. Purga cachés y ajusta reglas de cacheo.
Segundo: prueba una URL de entrada conocida de extremo a extremo
Elige una entrada que definitivamente exista en la base de datos. No pruebes URLs “quizá”. Prueba la realidad.
Tercero: verifica la plomería de rewrite, luego vacía las reglas una vez (no 37 veces)
Si estás en Apache, comprueba mod_rewrite y los permisos de .htaccess. Si estás en Nginx, revisa la sección try_files. Luego vacía las reglas de rewrite de forma controlada.
Cuarto: si el sitio se mudó o cambiaron los permalinks, diseña redirecciones antes de tocar cualquier otra cosa
No “arregles” 404 cambiando la estructura de permalinks a ciegas. Así conviertes un problema localizado de enrutamiento en un evento de reindexación SEO.
Qué significa realmente un 404 en una entrada de WordPress
“404 en entrada” es una frase que oculta tres fallos distintos:
- El servidor web no puede mapear la URL a WordPress (los permalinks bonitos requieren reglas de rewrite). Esto suele ser configuración de Nginx/Apache o falta de
.htaccess. - WordPress recibe la petición pero no puede resolverla (reglas de rewrite desactualizadas, estructura de permalinks incorrecta, etiquetas de rewrite faltantes, conflicto de plugins, siteurl/home mal, prefijos de idioma erróneos, etc.).
- WordPress la resuelve, pero algo más la intercepta (bucles de redirección, redirecciones canónicas a URLs muertas, capas de caché sirviendo respuestas obsoletas, WAF bloqueando, o un proxy enviando peticiones al backend equivocado).
La solución depende de cuál tengas. El error es tratar todos los 404 como “vaciar permalinks”. A veces vaciar funciona porque regenera reglas de rewrite. A veces no hace nada porque el servidor nunca pasa la petición a WordPress. A veces empeora las cosas porque enmascara una discrepancia entre estructuras de URL antiguas y nuevas.
Una cita para tener en mente mientras depuras: La esperanza no es una estrategia.
— Vince Lombardi
No es una cita de ingeniería de confiabilidad, pero una mente SRE la reconoce al instante: medir, verificar, luego cambiar.
Broma #1: Vaciar permalinks es como reiniciar una impresora: funciona con la frecuencia suficiente para convertirse en superstición, pero no lo bastante como para ser un plan.
Hechos interesantes y contexto histórico (porque este problema tiene una historia)
- Los permalinks bonitos no fueron “por defecto” siempre. Los primeros motores de blogs usaban a menudo URLs con query-strings como
?p=123. Las URLs limpias requirieron soporte de rewrite en el servidor. - WordPress depende de que el servidor web “mienta” por él. Con permalinks activados, tu servidor web finge que un archivo no existe y enruta las peticiones a
index.php, donde WordPress resuelve la entrada. - El
.htaccessde Apache hizo el hosting compartido barato—y frágil. WordPress se volvió ubicuo en parte porque podías controlar rewrites sin acceso root. Esa flexibilidad también hacía fácil romper cosas con permisos o módulos faltantes. - Nginx nunca soportó
.htaccesspor principio. Ese diseño es más rápido y seguro, pero significa que una migración de Apache a Nginx a menudo revela problemas de permalinks de inmediato. - El manejo de 404 por parte de Google evolucionó. Los motores de búsqueda mejoraron en eliminar URLs muertas rápidamente y tratar cadenas de redirección interminables como baja calidad. Eso aumenta el costo de cambios descuidados en URLs.
- 301 vs 302 se volvió una preocupación práctica de SEO. Las redirecciones “permanentes” (301) suelen transmitir señales más confiablemente que las temporales (302), aunque los motores modernos interpretan la intención. Aun así: usa 301 para contenido movido.
- El sistema de rewrite de WordPress está respaldado en la base de datos. Las reglas de rewrite se generan y almacenan; pueden quedar obsoletas si un plugin modifica rutas y luego se elimina.
- Las URLs canónicas importan. WordPress intentará redirigir URLs “casi correctas” a las canónicas; si tu lógica canónica apunta a una ruta no existente, puedes crear bucles 404 autoinfligidos.
- Los CDN normalizaron el cacheo de respuestas negativas. Cachear un 404 puede ser útil, pero cuando el 404 es accidental, has distribuido tu error globalmente.
Tareas prácticas: comandos, salidas, qué significan y qué hacer después
Estas tareas están escritas como un runbook de on-call: ejecutas un comando, interpretas la salida, tomas una decisión. Úsalas en orden, o salta a la sección que corresponda a tu stack.
Tarea 1: Comprobar si el 404 viene del origen o de un CDN
cr0x@server:~$ curl -sI https://example.com/2025/hello-world/ | sed -n '1,12p'
HTTP/2 404
date: Fri, 26 Dec 2025 10:22:11 GMT
content-type: text/html; charset=UTF-8
server: nginx
x-cache: HIT
cf-cache-status: HIT
Qué significa: Estás viendo un 404 que probablemente está cacheado (HIT). Si arreglas el origen pero no purgas, los usuarios seguirán viendo la falla.
Decisión: Purga la caché del CDN para una URL representativa una vez que verifiques que el origen está correcto. Si no puedes purgar, establece un TTL corto para 404 temporalmente.
Tarea 2: Confirmar si WordPress se ejecutó (404 de WordPress vs 404 del servidor)
cr0x@server:~$ curl -s https://example.com/2025/hello-world/ | grep -iE 'wp-content|wp-includes|rel="shortlink"|wp-json' | head
<link rel='shortlink' href='https://example.com/?p=123' />
<script src='https://example.com/wp-includes/js/jquery/jquery.min.js' id='jquery-core-js'></script>
Qué significa: WordPress generó la página (incluso si es la plantilla 404). Esto apunta a reglas de rewrite, desajuste de permalinks, entrada faltante o redirecciones canónicas—no al enrutamiento de archivos estáticos.
Decisión: Pasa a la inspección de reglas de rewrite y a comprobaciones a nivel de WordPress.
Tarea 3: Validar que la entrada existe vía WP-CLI
cr0x@server:~$ cd /var/www/html
cr0x@server:~$ wp post list --post_type=post --name=hello-world --fields=ID,post_title,post_status,post_name --format=table
+-----+-------------+------------+------------+
| ID | post_title | post_status| post_name |
+-----+-------------+------------+------------+
| 123 | Hello World | publish | hello-world|
+-----+-------------+------------+------------+
Qué significa: La entrada existe y está publicada. El 404 es de enrutamiento, no de eliminación de contenido.
Decisión: Enfócate en permalinks/rewrite/canonicalización y en la configuración del servidor web.
Tarea 4: Comprobar la estructura de permalinks actual en WordPress
cr0x@server:~$ wp option get permalink_structure
/%year%/%postname%/
Qué significa: WordPress espera URLs como /2025/hello-world/.
Decisión: Si tus URLs en producción son diferentes (p. ej., /blog/hello-world/), no adivines—restaura la estructura o redirige limpiamente.
Tarea 5: Inspeccionar el tamaño de las reglas de rewrite y si parecen pobladas
cr0x@server:~$ wp rewrite list --format=table | head -n 12
+-------------------------------+------------------------------------------+----------------+
| match | query | source |
+-------------------------------+------------------------------------------+----------------+
| ^wp-json/?$ | index.php?rest_route=/ | rest-api |
| ^wp-json/(.*)? | index.php?rest_route=/$matches[1] | rest-api |
| ^([0-9]{4})/([^/]+)/?$ | index.php?year=$matches[1]&name=$matches[2] | post |
| ^([0-9]{4})/page/([0-9]{1,})/?$ | index.php?year=$matches[1]&paged=$matches[2] | post |
Qué significa: Existen reglas de rewrite e incluyen patrones que coinciden con tu estructura de permalinks.
Decisión: Si las reglas están vacías o faltan los patrones esperados, vacía las reglas de rewrite (siguiente tarea) y busca conflictos de plugins o escrituras fallidas.
Tarea 6: Vaciar las reglas de rewrite de forma segura (CLI, una vez)
cr0x@server:~$ wp rewrite flush --hard
Success: Rewrite rules flushed.
Qué significa: WordPress regeneró las reglas y las escribió (o actualizó su caché interno). En Apache, el flush “hard” intenta actualizar .htaccess también.
Decisión: Vuelve a probar una URL que fallaba. Si sigue devolviendo 404, el problema probablemente sea el enrutamiento del servidor (.htaccess ignorado, configuración Nginx incorrecta) o lógica de redirección canónica.
Tarea 7: En Apache, confirmar que mod_rewrite está habilitado
cr0x@server:~$ apachectl -M 2>/dev/null | grep rewrite
rewrite_module (shared)
Qué significa: El módulo de rewrite está cargado.
Decisión: Si falta, habilítalo (según el paquete) y recarga Apache; sin él, los permalinks bonitos 404earán.
Tarea 8: En Apache, confirmar que el vhost permite overrides (para que .htaccess funcione)
cr0x@server:~$ sudo apachectl -S 2>/dev/null | sed -n '1,40p'
VirtualHost configuration:
*:80 example.com (/etc/apache2/sites-enabled/example.conf:1)
ServerRoot: "/etc/apache2"
cr0x@server:~$ sudo grep -R "AllowOverride" -n /etc/apache2/sites-enabled/example.conf
15: AllowOverride None
Qué significa: AllowOverride None deshabilita .htaccess. WordPress puede regenerar reglas todo el día y Apache las ignorará.
Decisión: Establece AllowOverride All (o al menos FileInfo) para el document root, recarga Apache y vuelve a probar. O mejor: mueve los rewrites al config del vhost por rendimiento y claridad.
Tarea 9: En Apache, verificar que .htaccess exista y sea legible
cr0x@server:~$ ls -la /var/www/html/.htaccess
-rw-r--r-- 1 www-data www-data 612 Dec 26 10:10 /var/www/html/.htaccess
Qué significa: El archivo existe y los permisos parecen correctos.
Decisión: Si falta o está owned por root con permisos restrictivos, corrige la propiedad/permiso y vuelve a vaciar las reglas de rewrite.
Tarea 10: En Nginx, confirmar que usas un try_files compatible con WordPress
cr0x@server:~$ sudo nginx -T 2>/dev/null | grep -n "try_files" | head
147: try_files $uri $uri/ /index.php?$args;
Qué significa: Esta es la línea canónica de enrutamiento para WordPress. Si falta, los permalinks suelen 404 porque Nginx busca un archivo que no existe y devuelve 404.
Decisión: Si ves algo como try_files $uri =404;, corrige el bloque location y recarga Nginx.
Tarea 11: Confirmar que PHP-FPM es accesible (un “404” puede ser una falla de upstream enmascarada)
cr0x@server:~$ systemctl status php8.2-fpm --no-pager
● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled)
Active: active (running)
Qué significa: PHP-FPM está en ejecución; bien.
Decisión: Si está caído o inestable, arregla eso primero. Los bugs de enrutamiento no importan si la app no puede ejecutarse con fiabilidad.
Tarea 12: Comprobar valores de “home” y “siteurl” tras migraciones
cr0x@server:~$ wp option get home
https://example.com
cr0x@server:~$ wp option get siteurl
https://example.com
Qué significa: Estos controlan cómo WordPress construye URLs canónicas y enlaces internos. Valores erróneos pueden crear redirecciones a hosts o rutas muertas, lo que parece 404 para los usuarios.
Decisión: Si apuntan a un dominio antiguo, corrígelos y purga cachés. Luego verifica el comportamiento de redirección canónica.
Tarea 13: Identificar si las redirecciones canónicas interfieren
cr0x@server:~$ curl -sI https://example.com/2025/hello-world | sed -n '1,12p'
HTTP/2 301
date: Fri, 26 Dec 2025 10:23:01 GMT
location: https://example.com/2025/hello-world/
Qué significa: WordPress (o el servidor) normaliza la barra final. Eso está bien.
Decisión: Si el Location apunta a un lugar incorrecto (dominio antiguo, ruta base equivocada como /blog/), corrige home/siteurl, la estructura de permalinks o las redirecciones del servidor.
Tarea 14: Verificar que una entrada se resuelve por ID incluso si los permalinks fallan
cr0x@server:~$ curl -sI "https://example.com/?p=123" | sed -n '1,12p'
HTTP/2 200
date: Fri, 26 Dec 2025 10:23:22 GMT
content-type: text/html; charset=UTF-8
server: nginx
Qué significa: WordPress puede servir la entrada. Tu contenido está bien. El enrutamiento “bonito” está roto.
Decisión: Mantén el sitio en línea cambiando temporalmente los permalinks a “Plain” si es necesario (a corto plazo), pero necesitarás redirecciones y un plan cuidadoso para evitar daño SEO. Mejor: arregla los rewrites correctamente.
Tarea 15: En Nginx, detectar cacheo “solo estático” accidental que devuelve 404
cr0x@server:~$ sudo nginx -T 2>/dev/null | grep -n "location ~ \\\\.php" -n | head
162: location ~ \.php$ {
cr0x@server:~$ sudo nginx -T 2>/dev/null | sed -n '150,190p'
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
Qué significa: El enrutamiento básico es correcto. Si tu config en cambio tuviera un bloque location para / devolviendo 404 para rutas desconocidas, romperías los permalinks.
Decisión: Si las configuraciones son complejas (múltiples bloques location), simplifica hasta que los permalinks funcionen, luego reintroduce optimizaciones con cuidado.
Tarea 16: Buscar reglas de redirección que accidentalmente coman URLs de entradas
cr0x@server:~$ sudo nginx -T 2>/dev/null | grep -n "return 301\|rewrite " | head -n 20
88: return 301 https://example.com$request_uri;
205: rewrite ^/blog/(.*)$ /$1 permanent;
Qué significa: Tienes reglas de rewrite/redirección. La reescritura /blog/ podría ser correcta—o podría quitar un prefijo necesario y crear 404s si WordPress está configurado para incluirlo.
Decisión: Valida la intención de la redirección frente a la estructura real de permalinks y las URLs históricas. No “limpies” reglas de rewrite durante un outage a menos que te gusten las sorpresas.
Tarea 17: Inspeccionar el .htaccess generado por WordPress (Apache)
cr0x@server:~$ sed -n '1,120p' /var/www/html/.htaccess
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Qué significa: Este es el bloque estándar de WordPress. Si falta o está malformado, los permalinks harán 404.
Decisión: Restaura el bloque de WordPress (con cuidado, preservando otras directivas), luego vacía las reglas de rewrite y vuelve a probar.
Tarea 18: Revisar logs del servidor para la URL que falla
cr0x@server:~$ sudo tail -n 50 /var/log/nginx/access.log
203.0.113.10 - - [26/Dec/2025:10:24:01 +0000] "GET /2025/hello-world/ HTTP/2.0" 404 548 "-" "Mozilla/5.0"
cr0x@server:~$ sudo tail -n 80 /var/log/nginx/error.log
2025/12/26 10:24:01 [error] 12345#12345: *910 open() "/var/www/html/2025/hello-world/index.html" failed (2: No such file or directory), client: 203.0.113.10, server: example.com, request: "GET /2025/hello-world/ HTTP/2.0", host: "example.com"
Qué significa: Nginx intentó abrir una ruta de archivo (estática) y falló, lo que sugiere que no enruta a index.php. Eso es un clásico de try_files mal configurado o un location en conflicto.
Decisión: Arregla el bloque location / de Nginx y recarga.
Causas raíz por stack: WordPress, Apache, Nginx, CDN
Causes a nivel WordPress (WordPress se ejecuta, aún así 404)
- Reglas de rewrite obsoletas tras cambios de plugin/theme o migraciones. Solución: vaciar reglas de rewrite vía WP-CLI; confirma que la estructura de permalinks coincide con las URLs esperadas.
- Desajuste en la estructura de permalinks (el sitio espera
/%postname%/pero los enlaces son/%year%/%postname%/). Solución: restaura la estructura previa o implementa redirecciones que preserven las URLs antiguas. home/siteurlincorrectos que causan redirecciones canónicas a rutas/dominios muertos. Solución: corrige las opciones y verifica redirecciones.- Tipos de post personalizados y slugs de rewrite cambiados. Solución: re-registra los tipos con argumentos de rewrite consistentes; vacía reglas; añade redirecciones para slugs antiguos.
- Plugins en conflicto que se enganchan a rewrites, redirecciones o canonicalización. Solución: desactiva temporalmente el plugin sospechoso, confirma el enrutamiento, luego ajusta la configuración.
- Multisite / plugins de idioma que añaden prefijos (
/en/) que el servidor no enruta correctamente. Solución: asegura que el rewrite del servidor pase rutas prefijadas a WordPress.
Causas en Apache (los permalinks bonitos dependen de rewrite + overrides)
mod_rewriteno cargado. Síntoma: todos los permalinks bonitos 404, pero?p=IDfunciona.AllowOverride Noneimpide que.htaccessse aplique. WordPress “escribe” reglas pero Apache las ignora..htaccessfaltante o corrupto. Puede ocurrir durante despliegues, endurecimiento de permisos o builds de contenedores.- DocumentRoot erróneo (el vhost apunta al directorio incorrecto) por lo que las peticiones nunca llegan al WordPress que posee la base de datos.
Causas en Nginx (sin el salvavidas .htaccess)
- Falta de
try_files ... /index.php?$args;. Esta es la razón número 1 por la que “entradas 404” después de migrar a Nginx. - Bloques de location demasiado agresivos que cortocircuitan el enrutamiento (
location / { try_files $uri =404; }), o locations regex que ganan precedencia inesperadamente. - Parámetros fastcgi incorrectos causando comportamientos extraños en PHP; a veces se manifiesta como “funciona para admin, no para entradas” según las rutas.
Causas en CDN / reverse proxy
- Respuestas 404 cacheadas (incluyendo cache negativo). Arreglas el origen, pero el mundo sigue viendo la respuesta antigua.
- Reglas de redirección en el edge que reescriben rutas (
/blog/quitando o añadiendo) sin que WordPress esté configurado para coincidir. - Desajuste en la terminación HTTPS donde WordPress piensa que está en HTTP; las redirecciones canónicas rebotan y pueden llevar a variantes muertas.
Arreglar permalinks sin romper el SEO
Aquí está la verdad operativa: la mayoría de “arreglos de permalinks en WordPress” cambian URLs accidentalmente. Cambiar URLs no es inherentemente malo. Cambiar URLs sin un plan de redirecciones es mala praxis.
Decide qué intentas hacer realmente
Hay dos objetivos diferentes que la gente confunde:
- Restaurar el enrutamiento funcionando sin cambiar URLs públicas. Esto es una corrección de incidente. Amigable con SEO.
- Cambiar la estructura de URL de forma intencional. Esto es una migración/gestión de cambios. Necesita mapeo, redirecciones y validación.
Si solo quieres que las entradas dejen de 404ear, probablemente buscas el objetivo #1.
Regla #1: restaura primero la antigua estructura de permalinks
Si las entradas 404ean porque alguien cambió los permalinks, el movimiento SEO más seguro es revertir a la estructura que los motores ya conocen. Después puedes planear mejoras de URL cuando nadie te esté llamando.
Operativamente: esto reduce el radio del problema. En términos de SEO: preserva la continuidad de URLs indexadas, enlaces entrantes y métricas históricas de engagement.
Regla #2: cuando debas cambiar URLs, implementa redirecciones 301 con política de un solo salto
Una estrategia limpia de redirección se ve así:
- URL antigua → URL nueva (301), exactamente un salto.
- Ninguna URL antigua debería redirigir a una URL intermedia que luego redirige otra vez.
- Ninguna redirección debe aterrizar en un 404 o en una página soft-404.
Las cadenas de redirección desperdician el budget de rastreo y hacen el debugging miserable. También tienden a acumularse como pelusas: silenciosamente, hasta que alguien revisa debajo del sofá.
Regla #3: mantiene la identidad del contenido estable
Los buscadores tratan una URL como un “puntero de identidad de contenido”. Si cambias URLs, mantén todo lo demás estable:
- Mismo contenido (no edites masivamente durante cambios de URL).
- Mismo título y metadatos salvo que haya razón.
- Etiquetas canónicas que apunten a la URL final, no a las legacy.
Regla #4: decide dónde viven las redirecciones (y sé consistente)
Puedes implementar redirecciones en varias capas. Elige una capa primaria para evitar duplicación y bucles.
- En el servidor web (Nginx/Apache): Rápido, fiable, bueno para patrones simples (p. ej., quitar
/index.php/, cambios de prefijo antiguo). - En WordPress (plugin o functions.php): Flexible, pero añade carga a la app y puede fallar si WordPress no se ejecuta.
- En CDN/edge: Muy rápido y global, pero fácil de malconfigurar a escala. También puede enmascarar el comportamiento del origen.
Mi preferencia: redirecciones basadas en patrones en el servidor web, redirecciones con conocimiento del contenido dentro de WordPress solo cuando realmente las necesitas.
Regla #5: verifica con muestreo y con logs
No verifiques una migración de URLs haciendo clic en tres enlaces y declarando victoria. Verifica con:
- Un conjunto de URLs antiguas de muestra (posts de mayor tráfico, más posts aleatorios de long-tail).
- Comprobaciones de códigos de estado (espera 301 y luego 200).
- Logs de acceso: asegura que bots y usuarios estén aterrizando en 200s, no en ping-pong entre redirecciones.
Broma #2: El SEO es la única disciplina donde la gente entra en pánico por un 302 como si fuera una brecha de seguridad.
Errores comunes (síntoma → causa raíz → solución)
1) “Solo las entradas 404, pero las páginas funcionan”
Síntoma: /about/ funciona, /2025/my-post/ 404ea.
Causa raíz: La estructura de permalinks incluye segmentos de fecha, pero las reglas de rewrite se generaron para una estructura distinta; o los rewrites del servidor son demasiado estrechos (p. ej., solo coinciden slugs de primer nivel).
Solución: Confirma permalink_structure; vacía reglas de rewrite; asegura que Nginx enrute todas las rutas a través de index.php cuando no exista archivo.
2) “Admin funciona, front-end de entradas 404”
Síntoma: /wp-admin/ funciona, la mayoría de URLs públicas fallan.
Causa raíz: El servidor está configurado para permitir endpoints PHP explícitos pero no rutas “bonitas”; falta try_files o reglas de rewrite de Apache.
Solución: Arregla location / de Nginx o el soporte de .htaccess en Apache; retesta con ?p=ID para aislar.
3) “Todo 404 después de migrar de Apache a Nginx”
Síntoma: El sitio carga parcialmente, pero las URLs limpias fallan.
Causa raíz: Esperar que .htaccess se transfiera. Nginx lo ignora.
Solución: Añade una config de Nginx amigable con WordPress con try_files $uri $uri/ /index.php?$args; y el bloque correcto para PHP.
4) “La solución funcionó para mí pero no para los usuarios”
Síntoma: Yo obtengo 200; otros obtienen 404.
Causa raíz: Caché CDN de un 404; split-brain entre múltiples orígenes; o nodos de caché antiguos sirviendo contenido obsoleto.
Solución: Purga la caché edge para las rutas afectadas; verifica el origen directamente (evita el CDN si es posible); asegura que todos los orígenes tengan configuración y reglas de rewrite idénticas.
5) “Cambiar a permalinks Plain lo arregla”
Síntoma: /?p=123 funciona; las URLs bonitas no.
Causa raíz: No se está haciendo el rewrite en la capa del servidor.
Solución: No lo dejes en Plain como “solución”. Arregla los rewrites y vuelve a la estructura bonita, con redirecciones si cambiaste URLs públicas mientras tanto.
6) “Tras cambiar la estructura de permalinks, el tráfico cae y Search Console avisa”
Síntoma: Muchas alertas de 404 para URLs antiguas.
Causa raíz: La estructura cambió sin redirecciones; o existen redirecciones pero encadenan/buclean; o las etiquetas canónicas apuntan mal.
Solución: Implementa 301 mapeando antiguo → nuevo; elimina cadenas; confirma que las etiquetas canónicas y el sitemap reflejen las nuevas URLs; valida con muestreo de logs.
Tres mini-historias corporativas (anonimizadas, técnicamente reales)
Historia 1: El incidente causado por una suposición errónea
Una compañía mediana migró un sitio de marketing WordPress desde una VM legacy con Apache a una plataforma de contenedores gestionada con Nginx delante. La checklist de migración incluía exportar/importar la base de datos, sincronizar medios y “asegurarse de que wp-admin funcione.” Funcionó. El equipo lo dio por terminado.
El lunes por la mañana: ventas reportaron “cada entrada del blog está rota.” La página principal cargaba, las páginas de categoría eran inconsistentes y las entradas individuales devolvían 404. El ingeniero on-call hizo el movimiento clásico: vació permalinks en la UI de admin. Sin cambio. Luego lo vació otra vez. Aún sin cambio. Comienza el pánico.
La suposición errónea fue sutil y común: asumieron que WordPress “posee los permalinks.” En Apache, WordPress parece poseerlos porque puede escribir .htaccess. En Nginx, WordPress no posee nada a menos que el servidor esté configurado para pasar rutas desconocidas a index.php.
La solución fue un cambio de una línea en try_files en el bloque de servidor adecuado, más un reload. Las entradas sirvieron 200 de inmediato. La acción del postmortem fue incluso más importante: añadir una prueba sintética para una URL de post conocida (no la página principal) a las puertas de despliegue.
No necesitaron heroísmos. Necesitaron una mejor definición de “funciona”.
Historia 2: La optimización que salió mal
Un equipo empresarial tenía un sitio WordPress detrás de un CDN y una capa de reverse proxy. Alguien notó una tasa alta de cache misses y decidió “optimizar” cacheando respuestas 404 en el edge con un TTL largo. El argumento parecía racional: los 404 son comunes por bots y cachearlos reduce carga del origen.
Entonces un editor publicó una campaña importante y la compartió en redes. En minutos, la primera ola de tráfico golpeó una ventana breve donde los rewrites estaban rotos en un nodo de origen (un deploy con latencia). El CDN cacheó el 404 para esa URL. No por segundos. Por horas.
Arreglaron el origen rápido, pero internet siguió viendo el 404 cacheado. Llegaron tickets de soporte. El equipo de marketing creyó que “la solución no funcionó”, porque desde su perspectiva no había funcionado. El SRE de turno tuvo que rastrear headers para darse cuenta de que el 404 era un artefacto distribuido, no una respuesta actual del origen.
La lección: cachear 404 puede estar bien, pero solo con TTL cortos y alcance cuidadoso. Si cacheas negativos demasiado agresivamente, conviertes un fallo temporal de enrutamiento en una outage durable.
Terminaron con una política matizada: TTL corto para 404s, sin cache para patrones de contenido conocidos como /%year%/%postname%/, y un hook de purge-on-publish para rutas de alto valor.
Historia 3: La práctica aburrida pero correcta que salvó el día
Una gran organización corría múltiples propiedades WordPress y había sido quemada por cambios de permalinks años antes. Así que implementaron una práctica aburrida: cada despliegue incluía una pequeña suite de chequeos sintéticos con curl desde fuera de la red.
No “el sitio está arriba.” URLs específicas: una entrada conocida, una página conocida, una categoría conocida y una URL legacy conocida que debería 301ear a un destino canónico. Los chequeos corrían tanto contra el endpoint del CDN como contra el endpoint de origen.
Durante una actualización rutinaria, una nueva plantilla de config de Nginx accidentalmente removió la línea try_files para un entorno. El despliegue tuvo éxito, las comprobaciones de salud siguieron en verde (solo probaban /), pero las comprobaciones sintéticas fallaron inmediatamente en la URL de post conocida. Se hizo rollback antes de que alguien lo notara públicamente.
Sin drama. Sin reunión de emergencia. Solo una puerta fallada y una corrección silenciosa. Así es la “confiabilidad” cuando funciona: es casi decepcionantemente poco interesante.
Listas de verificación / plan paso a paso
Plan A: Restaurar permalinks funcionando con mínimo riesgo SEO (recomendado para incidentes)
- Identifica un ID de post conocido usando WP-CLI (
wp post list). Anótalo. - Prueba
?p=ID. Si eso retorna 200, el contenido está bien y los rewrites son el problema. - Revisa la estructura de permalinks (
wp option get permalink_structure). Confirma que coincida con tus URLs históricas. - Vacía las reglas de rewrite una vez (
wp rewrite flush --hard). - Arregla el enrutamiento del servidor:
- Nginx: confirma
try_files $uri $uri/ /index.php?$args; - Apache: confirma
mod_rewrite,AllowOverridey el bloque de WordPress en.htaccess
- Nginx: confirma
- Verifica un conjunto representativo de URLs (top 10 posts, más 10 posts antiguos aleatorios). Usa cabeceras curl, no solo clics en navegador.
- Purgar cachés CDN para las rutas afectadas una vez que el origen esté correcto.
- Monitorea logs por la tasa de 404 y de redirecciones; asegura que los bots vean 200 para las URLs canónicas.
Plan B: Cambiaste permalinks intencionalmente (migración / solicitud de cambio)
- Congela la estructura de permalink objetivo. Decídela una vez. No la “ajustes” en medio de la migración.
- Exporta un mapa de URLs:
- Patrones de URL antiguos (estructura previa)
- Patrones de URL nuevos (estructura nueva)
- Implementa redirecciones 301:
- Prefiere reglas basadas en patrones en Nginx/Apache cuando sea posible
- Usa redirecciones a nivel WordPress solo para excepciones
- Actualiza enlaces internos si es necesario (WordPress normalmente generará nuevos permalinks automáticamente; vigila enlaces hard-coded en contenido).
- Valida etiquetas canónicas apuntando a las nuevas URLs y que las URLs antiguas redirijan al mismo destino canónico.
- Valida a escala con muestreo y logs; busca cadenas de redirección y clusters de 404.
- Mantén las redirecciones por largo tiempo. “Largo tiempo” significa lo suficientemente largo para que enlaces antiguos y marcadores dejen de usarse. En términos corporativos: más tiempo que nadie quiere, menos que para siempre.
Plan C: Contención temporal cuando no puedes arreglar rewrites inmediatamente
- Cambia permalinks a Plain (
/?p=ID) solo como último recurso y temporalmente. - Pon un banner en las notas del incidente: “Permalinks Plain habilitados; riesgo SEO; revertir después de arreglar rewrites.”
- Implementa redirecciones desde las URLs bonitas antiguas a
?p=IDsolo si tienes un mapeo fiable (a menudo no lo tienes). De lo contrario solo crearás redirecciones incorrectas. - Arregla los rewrites correctamente, restaura la estructura de permalinks y luego quita los hacks de contención.
Preguntas frecuentes
1) ¿Por qué las entradas 404 pero la página principal carga?
La página principal suele ser / que puede resolverse incluso cuando los rewrites están rotos. Las entradas dependen de rewrites para enrutar /year/postname/ a index.php.
2) ¿Es seguro “Ajustes → Enlaces permanentes → Guardar”?
Usualmente sí—vacía reglas de rewrite. Pero si tu servidor ignora .htaccess (overrides de Apache deshabilitados) o estás en Nginx, no arreglará el enrutamiento. Trátalo como un paso diagnóstico, no como la solución final.
3) ¿Cuál es la prueba más rápida para confirmar que es un problema de rewrite?
Solicita /?p=POST_ID. Si eso retorna 200 pero la URL bonita 404ea, tus rewrites están rotos.
4) ¿Debo cambiar a permalinks “Plain” para detener el outage?
Sólo como medida de contención temporal. Cambia las URLs públicas y puede crear una situación SEO desordenada a menos que redirijas correctamente. Arregla la plomería de rewrite en su lugar.
5) ¿Cómo arreglo permalinks en Nginx?
Asegúrate de que el location / del sitio incluya try_files $uri $uri/ /index.php?$args; y que las peticiones PHP pasen a PHP-FPM. Luego recarga Nginx y vuelve a probar.
6) ¿Cómo arreglo permalinks en Apache?
Asegúrate de que mod_rewrite esté habilitado, tu vhost permita overrides (AllowOverride) y exista el bloque de rewrite de WordPress en .htaccess. Luego vacía las reglas de rewrite una vez.
7) ¿Las redirecciones dañan el SEO?
Las redirecciones son normales. Las URLs rotas son peores. Usa redirecciones 301 para movimientos permanentes, evita cadenas y asegura que la URL final devuelva 200 con el contenido esperado.
8) ¿Por qué sigo viendo 404 después de arreglar la config del servidor?
La razón más común: CDN cacheó el 404, caché del navegador, o arreglaste un origen pero no todos. Revisa cabeceras de respuesta para hits de cache y compara comportamiento origen vs CDN.
9) ¿Un plugin puede causar 404 en entradas?
Sí. Plugins SEO, de multilingüe, de membresía y de tipos de post personalizados pueden registrar reglas de rewrite o redirecciones. Desactiva temporalmente el plugin sospechoso, vacía rewrites y retesta.
10) ¿Cómo evito esto en futuros despliegues?
Añade chequeos sintéticos para una URL de post conocida y una redirección legacy conocida. Pasa despliegues solo si esos chequeos pasan. También mantén la config del servidor en control de versiones y revisa los rewrites como código de aplicación.
Conclusión: próximos pasos que puedes lanzar hoy
Si las entradas de WordPress están 404eando, no empieces con superstición. Empieza con clasificación: 404 del servidor vs 404 de WordPress vs 404 cacheado. Luego demuestra que el contenido existe vía ?p=ID. Desde ahí, arregla la capa de enrutamiento—soporte de rewrite de Apache o try_files en Nginx—y vacía las reglas de rewrite una vez.
Si los permalinks cambiaron intencional o accidentalmente, trátalo como una migración de URLs. Restaura la estructura antigua si es posible. Si no, implementa redirecciones 301 limpias de un solo salto y valida con muestreo y logs. Luego purga cachés para que la corrección realmente llegue a los usuarios.
Pasos prácticos a seguir:
- Elige una URL de post rota y ejecuta las comprobaciones de cabeceras (Tarea 1 + Tarea 13).
- Confirma que la entrada existe y que
?p=IDretorna 200 (Tarea 3 + Tarea 14). - Verifica el enrutamiento del servidor (
try_filesen Nginx o.htaccess/AllowOverrideen Apache). - Vacía las reglas de rewrite una vez, vuelve a probar y luego purga la caché del CDN.
- Añade una puerta de despliegue: una URL de post conocida debe devolver 200, siempre.