WordPress «Se le está redirigiendo»: detener bucles de redirección por SSL y cookies

¿Te fue útil?

Si alguna vez has accedido a wp-admin, visto el spinner y luego te han devuelto a la página de inicio de sesión como si nada hubiera pasado—bienvenido al mundo de los bucles de redirección de WordPress. El navegador dice “demasiadas redirecciones” o WordPress muestra “You are being redirected.” Tus usuarios dicen “el sitio está caído.” Tú dices palabras inapropiadas para un registro de cambios.

Este modo de fallo rara vez es “WordPress está roto.” Casi siempre es que la idea de tu petición sobre HTTP vs HTTPS no coincide con la idea de WordPress, o una cookie que nunca se mantiene. La solución suele ser pequeña. La caza puede ser larga si no lo tratas como un incidente SRE: reproducir, observar, acotar, cambiar una cosa, verificar.

Qué significa realmente este error (y por qué ocurre el bucle)

Los bucles de redirección en WordPress son un desacuerdo entre capas. Tu navegador sigue instrucciones como: “ir a https://…”, luego “no, ir a http://…”, luego “en realidad, otra vez https.” O inicias sesión, pero la cookie de autenticación no coincide con el host/esquema/ruta que WordPress espera, así que WordPress decide que no has iniciado sesión y te redirige de nuevo al login, que lo intenta otra vez y vuelve a fallar. Una y otra vez.

WordPress emite redirecciones desde varios lugares:

  • Canonicalización de URL del sitio (desajuste Home/SiteURL, o esquema/host incorrecto): WordPress intenta imponer lo que cree que es la URL del sitio.
  • Forzado de SSL en administración (FORCE_SSL_ADMIN, reglas de wp-admin): las rutas de login y administración se fuerzan a HTTPS.
  • Cookies de autenticación origen (COOKIE_DOMAIN, cookies seguras, cookie path): si las cookies no coinciden, se comporta como si nunca hubieras iniciado sesión.
  • Decisiones de proxy/CDN (X-Forwarded-Proto, CF-Visitor, offload TLS): WordPress ve “HTTP” en el origen mientras el usuario ve “HTTPS” en el navegador.
  • Reescrituras del servidor (.htaccess, Nginx return 301, redirecciones a nivel de aplicación): múltiples motores de redirección compitiendo por el control.

En producción, casi siempre tienes al menos tres sistemas que creen ser “la única capa válida para redirecciones”: el CDN, el load balancer/reverse proxy y el servidor de origen. WordPress es el cuarto. Si dos de ellos discrepan sobre esquema o host, obtienes un bucle. Si están de acuerdo pero la cookie no persiste, obtienes un bucle de login que se parece, pero no es el mismo.

Una regla seca que funciona: elige exactamente una capa para encargarse de HTTP→HTTPS y de www→no-www. Todos los demás deben pasar la petición y establecer cabeceras con precisión.

Guía rápida de diagnóstico

1) Confirma qué tipo de bucle es (esquema/host vs cookie)

Si la cadena de redirecciones alterna entre http y https, o entre www y el apex, estás en el infierno de la canonicalización. Si te sigue devolviendo a /wp-login.php tras un POST exitoso, probablemente estés en el infierno de las cookies.

2) Observa la cadena de redirección desde fuera, no desde tu navegador

Usa curl para ver las cabeceras Location. Tu navegador ayuda hasta que no; oculta detalles con “demasiadas redirecciones”.

3) Identifica el punto de terminación SSL

¿Dónde termina TLS? ¿CDN? ¿Load balancer? ¿Nginx en el host? Si el origen ve HTTP mientras el cliente ve HTTPS, debes pasar la información del esquema mediante cabeceras y enseñar a WordPress a confiar en ellas.

4) Comprueba la “verdad” de WordPress: Home y SiteURL

WordPress guarda estos valores en la base de datos y a veces en wp-config.php. Si no coinciden con la URL pública real, WordPress intentará “arreglarlo” con redirecciones para siempre.

5) Sólo entonces mira plugins, caché y reglas de reescritura raras

Los plugins sí causan bucles, pero la mayoría de los bucles atribuidos a “plugins” siguen siendo desajustes de esquema/cookie. Desactiva plugins al final, no al principio. Quieres depurar sistemas, no hacer exorcismos.

Una cita, porque aplica: «La esperanza no es una estrategia.» — General Gordon R. Sullivan

Taxonomía de bucles de redirección: SSL vs cookies vs caché

A) Terminación SSL / desajuste de cabeceras de proxy

Configuración clásica: el cliente se conecta vía HTTPS a un CDN o load balancer, que se conecta al origen vía HTTP. WordPress corre en el origen y ve $_SERVER['HTTPS'] como off y el puerto del servidor como 80. WordPress construye URLs como http://, luego el borde fuerza https://, luego WordPress fuerza http://, y has creado una máquina de movimiento perpetuo que sólo produce miseria.

Patrón de solución: asegúrate de que el borde establezca X-Forwarded-Proto: https (y/o una cabecera del proveedor), y asegúrate de que el origen y WordPress lo interpreten correctamente. Luego asegúrate de que sólo una capa haga cumplir las redirecciones HTTPS.

B) Cookie no establecida / no devuelta (el bucle de login)

Entras credenciales, “inicias sesión”, y luego vuelves a la pantalla de login. Eso significa que WordPress no ve una cookie de autenticación válida en la siguiente petición. Las causas incluyen:

  • Cookies marcadas como Secure que se establecen sobre HTTPS pero el sitio se accede por HTTP (o viceversa).
  • Dominio de cookie incorrecto (desajuste COOKIE_DOMAIN entre example.com y www.example.com).
  • Proxy reescribiendo cabeceras Host; WordPress establece cookies para el dominio equivocado.
  • Políticas SameSite interactuando con flujos de login embebidos (menos común para wp-admin estándar, más común en flujos SSO).
  • Capa de caché cacheando la página de login o respuestas de redirección. Sí, hay gente que hace esto. No, no termina bien.

C) Redirecciones canónicas en conflicto (www, barras finales, mapeo multisite)

A WordPress le gusta una URL canónica. A tu CDN también. A tu reverse proxy también. Y a cinco plugins distintos que quieren “ayudar al SEO”. Cuando varios componentes “corrigen” la URL de forma diferente—añadiendo/removiendo www, forzando una barra final, normalizando mayúsculas, o empujando /index.php—puedes crear un bucle sin involucrar SSL en absoluto.

D) Caché y efectos secundarios de “optimización”

Las respuestas de redirección son cacheables. Algunas cachés almacenan 301/302 agresivamente cuando se les indica, y algunos administradores por accidente las cachean mediante reglas demasiado amplias. Si una caché conserva una cabecera Location mala, puedes arreglar el origen y seguir viendo el bucle desde ciertas geografías o sólo para ciertos usuarios.

Broma #1: Los bucles de redirección son como la política de oficina—todos insisten en que están “alineando”, y nadie es responsable del resultado real.

Tareas prácticas (comandos, salidas, decisiones)

Estas tareas están pensadas para ejecutarse desde un shell de administrador en el host de origen, o desde un bastión. Si no puedes ejecutar comandos, adáptalos a tu entorno. El objetivo es el mismo: recopilar evidencia y luego decidir.

Task 1: Inspect the redirect chain with curl

cr0x@server:~$ curl -sS -D - -o /dev/null -L --max-redirs 10 https://example.com/wp-admin/ | sed -n '1,120p'
HTTP/2 302
location: https://example.com/wp-login.php?redirect_to=https%3A%2F%2Fexample.com%2Fwp-admin%2F&reauth=1
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly

HTTP/2 302
location: https://example.com/wp-admin/
set-cookie: wordpress_logged_in_abc123=cr0x%7C1735900000%7Ctoken; path=/; secure; HttpOnly

HTTP/2 302
location: https://example.com/wp-login.php?redirect_to=https%3A%2F%2Fexample.com%2Fwp-admin%2F&reauth=1

Qué significa: Rebotamos entre wp-login y wp-admin incluso después de que se establece la cookie logged_in. Eso sugiere fuertemente que la cookie no se está devolviendo o no es válida para solicitudes posteriores.

Decisión: Cambia a comprobaciones centradas en cookies: dominio, flag secure, cabeceras Host del proxy y caché de endpoints de autenticación.

Task 2: Check for http↔https flipping

cr0x@server:~$ curl -sS -I http://example.com/ | egrep -i '^(HTTP|location)'
HTTP/1.1 301 Moved Permanently
Location: https://example.com/

cr0x@server:~$ curl -sS -I https://example.com/ | egrep -i '^(HTTP|location)'
HTTP/2 301
location: http://example.com/

Qué significa: Tu borde redirige HTTP→HTTPS, pero tu origen (o app) redirige HTTPS→HTTP. Eso es un bucle limpio de dos nodos.

Decisión: Elige el esquema canónico (es 2025; es HTTPS), luego deshabilita la redirección conflictiva en una capa y arregla el manejo de forwarded-proto.

Task 3: Confirm what WordPress thinks the site URL is (WP-CLI)

cr0x@server:~$ cd /var/www/html
cr0x@server:/var/www/html$ sudo -u www-data wp option get home
http://example.com
cr0x@server:/var/www/html$ sudo -u www-data wp option get siteurl
http://example.com

Qué significa: WordPress cree que el sitio es HTTP. Si el sitio público es HTTPS, WordPress seguirá intentando “corregir” las cosas dependiendo de la configuración y plugins.

Decisión: Actualiza home y siteurl a HTTPS (tras confirmar que TLS se termina correctamente y que las cabeceras del proxy son correctas).

Task 4: Set Home/SiteURL safely with WP-CLI

cr0x@server:/var/www/html$ sudo -u www-data wp option update home 'https://example.com'
Success: Updated 'home' option.
cr0x@server:/var/www/html$ sudo -u www-data wp option update siteurl 'https://example.com'
Success: Updated 'siteurl' option.

Qué significa: Has cambiado las URLs canónicas en la BD. WordPress ahora generará URLs HTTPS.

Decisión: Vuelve a probar inmediatamente las cadenas de redirección. Si sigue en bucle, probablemente tengas una regla de redirección aguas arriba o un desajuste en el proxy.

Task 5: Check wp-config.php for hardcoded URL overrides

cr0x@server:~$ sudo egrep -n "WP_HOME|WP_SITEURL|FORCE_SSL_ADMIN|COOKIE_DOMAIN|COOKIEPATH|SITECOOKIEPATH" /var/www/html/wp-config.php
82:define('WP_HOME','http://example.com');
83:define('WP_SITEURL','http://example.com');

Qué significa: Incluso si arreglaste la BD, estas constantes la sobrescriben. Esa es una trampa común de “¿por qué no cambió nada?”.

Decisión: Cámbialas a HTTPS o elimínalas y gestiona mediante la BD (elige un plano de control; no mezcles casualmente).

Task 6: Verify what scheme the origin thinks it’s serving

cr0x@server:~$ sudo -u www-data php -r 'var_export([$_SERVER["HTTPS"]??null,$_SERVER["SERVER_PORT"]??null,$_SERVER["HTTP_X_FORWARDED_PROTO"]??null,$_SERVER["HTTP_HOST"]??null]);'
array (
  0 => NULL,
  1 => '80',
  2 => 'https',
  3 => 'example.com',
)

Qué significa: TLS se termina aguas arriba (HTTPS es null, puerto 80), pero el proxy envía X-Forwarded-Proto=https. WordPress no confiará automáticamente en esto a menos que la pila esté configurada para ello.

Decisión: Asegúrate de que el reverse proxy pase la cabecera de forma consistente, y configura WordPress/PHP para tratar X-Forwarded-Proto como autorizativa (con cuidado—sólo cuando confíes en el proxy).

Task 7: Inspect Nginx proxy headers (common cause)

cr0x@server:~$ sudo nginx -T 2>/dev/null | egrep -n "proxy_set_header (Host|X-Forwarded-Proto|X-Forwarded-For)|return 301|listen 443|listen 80" | sed -n '1,120p'
45:    listen 80;
61:    return 301 https://$host$request_uri;
90:    listen 443 ssl http2;
132:    proxy_set_header Host $host;
133:    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
134:    proxy_set_header X-Forwarded-Proto $scheme;

Qué significa: Si el origen está detrás de otro proxy, $scheme podría ser http incluso cuando el cliente usó HTTPS. Entonces WordPress ve forwarded-proto=http y genera redirecciones HTTP.

Decisión: Si TLS termina en el borde, establece X-Forwarded-Proto https (o pasa la cabecera proto del borde) entre proxies, no $scheme.

Task 8: Check Apache rewrite rules (.htaccess) for conflicting redirects

cr0x@server:~$ sudo sed -n '1,160p' /var/www/html/.htaccess
# BEGIN WordPress
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

Qué significa: Esto fuerza HTTPS en el origen. Si tu borde ya fuerza HTTPS pero habla con el origen sobre HTTP, Apache redirigirá a HTTPS en el host del origen—a veces al host equivocado, a veces a un nombre privado, y otras veces simplemente bucles con el borde.

Decisión: Mueve la aplicación del HTTPS al borde (recomendado) o termina TLS en el origen. No hagas las dos cosas a medias.

Task 9: Confirm Cloudflare/Flexible SSL-type behavior (header evidence)

cr0x@server:~$ curl -sS -I https://example.com/ | egrep -i "^(cf-|server:|location:|x-forwarded-proto:)"
server: cloudflare
cf-cache-status: DYNAMIC

Qué significa: Estás detrás de Cloudflare (o un CDN similar). Si el CDN está configurado en un modo que conecta al origen vía HTTP mientras presenta HTTPS a los clientes, debes asegurar que la pila de origen entienda el esquema real.

Decisión: Prefiere modos “Full”/TLS extremo a extremo y manejo consistente de forwarded-proto. También asegúrate de que el CDN no reescriba Location headers de formas inesperadas.

Task 10: Verify cookies are being sent back (curl cookie jar)

cr0x@server:~$ curl -sS -c /tmp/cj.txt -b /tmp/cj.txt -L --max-redirs 5 https://example.com/wp-login.php -o /dev/null -D - | egrep -i "set-cookie:|location:|HTTP/"
HTTP/2 200
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly

cr0x@server:~$ grep -v '^#' /tmp/cj.txt | sed -n '1,5p'
example.com	FALSE	/	TRUE	0	wordpress_test_cookie	WP%20Cookie%20check

Qué significa: La cookie está marcada como Secure y limitada a example.com y /. Si accedes vía www.example.com o por HTTP, no se enviará. Además, si un proxy reescribe el Host, el dominio de la cookie podría ser incorrecto.

Decisión: Asegura que el hostname público coincida con lo que usa WordPress y evita rebotar entre www y apex durante el login.

Task 11: Confirm Host header preservation through proxies

cr0x@server:~$ curl -sS -H 'Host: example.com' -I http://127.0.0.1/ | egrep -i "^(HTTP|location|set-cookie)"
HTTP/1.1 301 Moved Permanently
Location: https://example.com/

Qué significa: Tu vhost local responde correctamente cuando se establece Host. Si en su lugar ves redirecciones a un nombre interno, tu proxy/configuración del origen está filtrando nombres internos en las cabeceras Location.

Decisión: Arregla vhost/server_name y proxy_set_header Host; además confirma que home/siteurl de WordPress coincida con el host público previsto.

Task 12: Look for cached redirects at Nginx or a caching proxy

cr0x@server:~$ sudo egrep -R "proxy_cache|fastcgi_cache|expires|add_header Cache-Control|location = /wp-login.php|location ~ \\.php" -n /etc/nginx | sed -n '1,120p'
/etc/nginx/sites-enabled/example.conf:55:    fastcgi_cache WORDPRESS;
/etc/nginx/sites-enabled/example.conf:56:    add_header X-Cache $upstream_cache_status;
/etc/nginx/sites-enabled/example.conf:80:    location = /wp-login.php { include fastcgi_params; }
/etc/nginx/sites-enabled/example.conf:81:    fastcgi_cache WORDPRESS;

Qué significa: Alguien está cacheando respuestas PHP, incluyendo wp-login.php. Eso puede cachear redirecciones y Set-Cookie headers, produciendo bucles extraños que varían por usuario.

Decisión: Desactiva la caché para endpoints de login/admin y para respuestas que establecen cookies de autenticación. Cachea el front-end anónimo, no los flujos de autenticación.

Task 13: Verify WordPress is not mis-detecting HTTPS (quick mu-plugin fix test)

cr0x@server:~$ sudo install -d /var/www/html/wp-content/mu-plugins
cr0x@server:~$ sudo tee /var/www/html/wp-content/mu-plugins/00-proxy-https.php >/dev/null <<'PHP'
<?php
// Trust X-Forwarded-Proto only if coming from known proxies (adjust CIDRs).
$trusted = ['10.0.0.0/8','172.16.0.0/12','192.168.0.0/16'];
$remote = $_SERVER['REMOTE_ADDR'] ?? '';
function ip_in_cidrs($ip, $cidrs) {
  foreach ($cidrs as $cidr) {
    [$subnet,$bits] = explode('/', $cidr);
    $ip_long = ip2long($ip);
    $sub_long = ip2long($subnet);
    $mask = -1 << (32 - (int)$bits);
    if (($ip_long & $mask) === ($sub_long & $mask)) return true;
  }
  return false;
}
if (ip_in_cidrs($remote, $trusted)) {
  if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
  }
}
PHP

Qué significa: Esto es una prueba pragmática para forzar la detección de HTTPS cuando estás detrás de proxies confiables. No es “la” solución para todos los entornos, pero demuestra rápidamente si la detección del esquema es la culpable.

Decisión: Si los bucles desaparecen, implementa una solución más limpia a largo plazo en tu pila proxy/app y mantén el límite de confianza estricto.

Task 14: Check database-level Home/SiteURL without WP-CLI (for broken CLI)

cr0x@server:~$ mysql -N -e "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('home','siteurl');"
home	http://example.com
siteurl	http://example.com

Qué significa: Igual que con WP-CLI, pero funciona cuando la integración PHP/CLI está rota.

Decisión: Actualiza estos valores (con cuidado) si están mal. Si estás en multisite, detente y lee el FAQ de multisite primero.

Task 15: Confirm admin cookies aren’t being stripped by a security header policy

cr0x@server:~$ curl -sS -I https://example.com/wp-login.php | egrep -i "set-cookie|content-security-policy|strict-transport-security|x-frame-options"
strict-transport-security: max-age=31536000; includeSubDomains; preload

Qué significa: HSTS está bien y suele ser útil. Pero si estableces includeSubDomains y tienes subdominios legacy aún en HTTP, esos clientes se verán forzados a HTTPS y pueden alcanzar endpoints rotos—a veces alimentando un lío de redirecciones.

Decisión: Mantén HSTS, pero sólo después de verificar la cobertura TLS para todos los subdominios necesarios. No establezcas preload a la ligera.

Broma #2: Si tu WordPress está atrapado en un bucle de redirección, felicidades—tu sitio ha conseguido movimiento perpetuo, sólo que no del útil.

Tres microhistorias del mundo corporativo

1) El incidente causado por una suposición errónea: “El load balancer gestiona HTTPS, así que la app sabe que es HTTPS”

Acababan de migrar de una VM única con Apache a una pila “correcta”: CDN → load balancer → Nginx → PHP-FPM. La solicitud de cambio decía “sin cambios funcionales”. Esa línea ha terminado más tardes de lo que cualquier outage merece.

El sitio arrancó. La página principal parecía bien. Luego los editores intentaron entrar y obtuvieron el bucle “You are being redirected”. El ingeniero on-call hizo la danza estándar: borrar cookies del navegador, probar en incógnito, desactivar un par de plugins. Nada. Mientras tanto, el equipo de marketing descubrió nuevas formas de refrescar una página.

La suposición subyacente era sutil: porque el cliente usó HTTPS, la app sabría que era HTTPS. Pero TLS se terminaba en el load balancer, y el tráfico al origen era HTTP plano. Nginx establecía X-Forwarded-Proto usando $scheme, que en ese salto era http. WordPress vio HTTP, estableció expectativas no seguras y rebotó la redirección de administración.

La solución fue poco glamorosa e inmediata: establecer X-Forwarded-Proto basado en la cabecera entrante del load balancer, no en el esquema local; añadir un pequeño snippet de detección HTTPS en WordPress con un límite de confianza estricto para proxies; luego estandarizar la propiedad de redirecciones en el borde sólo. Tras eso, el bucle de login desapareció.

El postmortem fue aún menos glamoroso: “no asumas nada sobre el esquema; observa las cabeceras en cada salto.” Añadieron un endpoint de volcado de cabeceras de una línea para depuración interna y restringieron quién podía cambiar la lógica de cabeceras del proxy. El outage no fue heroico; fue un hecho faltante.

2) La optimización que salió mal: cachear wp-login.php “por rendimiento”

Otra organización tenía un problema de pico de tráfico. El front-end era WordPress y la tasa de aciertos de la caché era… aspiracional. Una iniciativa de rendimiento bienintencionada desplegó reglas agresivas de fastcgi_cache en Nginx. El objetivo era sensato: reducir carga PHP, reducir latencia, evitar costes de escalado.

En staging fue excelente. Luego llegó producción: fallos intermitentes de login, usuarios viendo redirecciones pos-login de otros usuarios, y un bucle de redirección extraño que sólo ocurría en ciertas regiones. No fallaba consistentemente, lo que lo hacía parecer “WordPress es inestable”. No lo era.

Habían cacheado respuestas de /wp-login.php y algunas redirecciones de /wp-admin/. Eso significaba Location headers cacheados y comportamiento cacheado de Set-Cookie, que básicamente es “reutilizar aleatoriamente vieja coreografía de autenticación”. Si quieres convertir una caché en un arma contra tu propio sistema de autenticación, esta es una forma eficiente de hacerlo.

La resolución: crear reglas explícitas de no-cache para /wp-login.php, /wp-admin/ y cualquier request/response que establezca cookies de autenticación. También hicieron la clave de caché que incluía esquema/host y unas cuantas cabeceras relevantes. El rendimiento bajó un poco. La fiabilidad se disparó. Es un trade-off que tomas cada vez.

Después, siguieron cacheando—pero sólo para GETs anónimos y sólo para páginas de contenido. El equipo también aprendió a tratar el cacheo de 301/302 como una capacidad controlada por cambios. Cachear redirecciones puede ser una característica; también puede ser un outage con gabardina.

3) La práctica aburrida pero correcta que salvó el día: una capa canónica de redirección + pruebas registradas

Un tercer equipo gestionaba WordPress para múltiples unidades de negocio, detrás de un CDN y dos capas de proxies. Ya les habían quemado antes, así que hicieron algo profundamente poco de moda: hicieron una regla y la documentaron.

La regla: el CDN posee HTTP→HTTPS y la normalización de www. El origen nunca emite redirecciones de esquema/host, sólo redirecciones a nivel de aplicación (como permalinks). Todos los proxies deben preservar Host y establecer forwarded proto de forma consistente. Home/SiteURL de WordPress debe coincidir con la URL pública, y cualquier override en wp-config.php está prohibido salvo que exista un ticket que explique por qué.

También construyeron una pequeña prueba de regresión de cadena de redirecciones como parte de la verificación de despliegue. Ejecutaba curl -IL contra endpoints clave (/, /wp-admin/, /wp-login.php) y verificaba: máximo 3 redirecciones, esquema final https, host final canónico, sin rebotar entre login/admin. Si la cadena cambiaba, el despliegue se bloqueaba.

Meses después, una actualización de un plugin de proveedor introdujo un nuevo comportamiento de redirección canónica que hubiera chocado con las reglas del CDN. La prueba lo detectó antes que los clientes. No necesitaron heroísmos; necesitaron la puerta aburrida que dice “no, hoy no”.

Errores comunes: síntoma → causa raíz → solución

1) “Demasiadas redirecciones” sólo en HTTPS

  • Síntoma: HTTP funciona (o redirige una vez), HTTPS entra en bucle.
  • Causa raíz: El origen piensa que las peticiones son HTTP porque TLS se termina aguas arriba; WordPress genera URLs HTTP y redirecciones.
  • Solución: Pasar y confiar en X-Forwarded-Proto=https correctamente; poner home/siteurl de WordPress a https; asegurar que sólo una capa aplique redirecciones de esquema.

2) Bucle de login: credenciales aceptadas, luego de vuelta a wp-login.php

  • Síntoma: POST a wp-login tiene éxito, luego redirige de vuelta al login con reauth=1.
  • Causa raíz: Cookie de auth no devuelta (desajuste de dominio, flag secure, caché o reescritura de Host).
  • Solución: Asegurar host consistente (www vs apex), correcto COOKIE_DOMAIN (o no establecerlo), no cachear endpoints de auth, preservar Host a través de proxies.

3) Alternancia entre www y non-www en Location headers

  • Síntoma: La cadena de redirección alterna entre example.com y www.example.com.
  • Causa raíz: El CDN impone un host; home/siteurl de WordPress o reescritura del servidor imponen el otro.
  • Solución: Elegir un host canónico, configurarlo en una sola capa, alinear home/siteurl de WordPress y eliminar reglas de reescritura en competencia.

4) Bucle de redirección aparece sólo después de habilitar HSTS

  • Síntoma: Algunos clientes quedan atascados; otros bien.
  • Causa raíz: HSTS fuerza HTTPS a subdominios que no están listos; un subdominio redirige a HTTP, que los navegadores rehúsan.
  • Solución: Quitar includeSubDomains hasta tener cobertura TLS completa, o arreglar TLS para todos los subdominios; evitar preload hasta estar seguro.

5) Bucle sólo para ciertas geografías / ISPs

  • Síntoma: Tickets de soporte vienen de una región; no puedes reproducir localmente.
  • Causa raíz: Caché del borde que guarda 301/302 obsoletos o configuración CDN inconsistente por POP.
  • Solución: Purga redirecciones cacheadas; reducir cachabilidad de redirecciones; verificar despliegue de configuración uniforme entre POPs.

6) Bucle comienza justo después de cambiar la URL del sitio en ajustes de WordPress

  • Síntoma: La administración se vuelve inaccesible inmediatamente tras cambiar la URL.
  • Causa raíz: La nueva URL no coincide con el vhost/ruteo real; WordPress te redirige a un host que no sirve WordPress.
  • Solución: Actualiza mediante WP-CLI o BD con cuidado; asegúrate de que DNS/vhost coincidan; añade temporalmente una entrada en hosts para pruebas.

7) Bucles de admin en multisite tras cambios de mapeo de dominios

  • Síntoma: La red de administración funciona en un dominio pero no en los sitios mapeados.
  • Causa raíz: Mapeo de dominios incorrecto o conflictos de dominio/ruta de cookies entre subsitios.
  • Solución: Confirma constantes de multisite y ajustes de domain mapping; alinea la configuración de cookies con la estrategia de mapeo; asegura que el proxy preserve Host por sitio.

Listas de comprobación / plan paso a paso

Paso a paso: arreglar un bucle SSL/proxy (el caso común)

  1. Observa la cadena de redirección con curl. Confirma si cambia esquemas o hosts.
  2. Identifica la terminación TLS: CDN, LB, origen. Dibuja el diagrama de saltos. No adivines.
  3. Elige el propietario de las redirecciones: normalmente el borde (CDN/LB) para esquema y host canónico.
  4. Deshabilita redirecciones en conflicto en otras capas (remueve return/rewrite de Nginx/Apache; audita plugins/WordPress que fuerzan SSL).
  5. Arregla cabeceras forwarded: preserva Host; establece X-Forwarded-Proto al esquema del cliente; asegúrate de que los saltos upstream→origen no lo sobrescriban mal.
  6. Enseña a WordPress a interpretar el esquema detrás de proxies (vía config/snippet de proxies confiables), pero no confíes en cabeceras de clientes arbitrarios en internet público.
  7. Establece home/siteurl de WordPress a la URL pública canónica (prefiere BD o constantes en wp-config, no ambas).
  8. Vuelve a probar la cadena de redirección buscando: máximas redirecciones, URL final, host consistente, esquema consistente.
  9. Purga cachés (CDN y proxies reversos) si las redirecciones estaban cacheadas.
  10. Añade una comprobación de regresión para que el próximo “pequeño cambio” no sea un incidente.

Paso a paso: arreglar un bucle de cookies/login

  1. Reproduce con curl cookie jar para confirmar que las cookies se establecen y se devuelven.
  2. Estabiliza el hostname: usa siempre el host canónico para login/admin. No rebotes entre www y apex.
  3. Comprueba el scope de la cookie: dominio y path. Evita forzar COOKIE_DOMAIN salvo necesidad.
  4. Asegura consistencia de cookies seguras: si las cookies son Secure, sirve login/admin por HTTPS de extremo a extremo.
  5. Deshabilita caché para endpoints de auth en todos los sitios: reglas CDN, Nginx/Apache, plugins.
  6. Comprueba preservación de Host a través de proxies; WordPress lo usa para construir redirecciones y cookies.
  7. Sólo entonces sospecha de plugins que alteren flujos de login, plugins de seguridad o integraciones SSO personalizadas.

Checklist operativo: qué registrar durante el incidente

  • URL(s) exactas que fallan y si afectan a usuarios anónimos o sólo autenticados.
  • Salida de la cadena de redirección (curl -IL con cabeceras) desde al menos un punto externo.
  • Dónde termina TLS y qué cabeceras se reenvían en cada salto.
  • Valores actuales de home/siteurl y cualquier override en wp-config.
  • Capas de caché en la ruta y si las redirecciones están cacheadas.
  • Qué cambió recientemente (regla CDN, plugin, migración, renovación de certificado, política del load balancer).

Hechos y contexto histórico

  • Hecho 1: Las primeras apps web dependían de variables de servidor como HTTPS=on; los reverse proxies rompieron esa suposición mucho antes de que fuera mainstream.
  • Hecho 2: La cabecera X-Forwarded-Proto surgió como estándar de facto porque las apps backend necesitaban conocer el esquema original del cliente tras la terminación TLS aguas arriba.
  • Hecho 3: WordPress almacena home y siteurl en la base de datos, una elección de diseño que facilitó movimientos/renombres—hasta que olvidas actualizarlos durante una migración.
  • Hecho 4: El login de WordPress depende de múltiples cookies (test cookie, logged_in, auth, secure_auth), y pueden aplicarse distintos paths/scopes según administración vs front-end.
  • Hecho 5: Las cachés se volvieron comunes delante de WordPress porque renderizar con PHP bajo carga es caro; cachear flujos de auth siempre fue mala idea, pero “siempre” no detuvo a nadie.
  • Hecho 6: HTTPS pasó de “útil para pagos” a “expectativa por defecto” principalmente por cambios en la UX de los navegadores y por incentivos de posicionamiento, lo que aumentó la frecuencia de bugs por desajustes HTTP/HTTPS.
  • Hecho 7: HSTS se creó para prevenir ataques de SSL stripping; operativamente, también significa que una mala configuración HTTPS puede quedarse en los clientes más tiempo del que toleras.
  • Hecho 8: Los códigos de estado de redirección importan: los 301 pueden ser cacheados agresivamente por navegadores y CDNs, haciendo que un error temporal sea sorprendentemente persistente.
  • Hecho 9: Existen modos tipo “Flexible SSL” para facilitar onboarding, pero también normalizan el patrón peligroso de HTTPS-en-borde y HTTP-en-origen, que es donde nacen muchos bucles.

Preguntas frecuentes

1) ¿Por qué WordPress dice “You are being redirected” en vez de mostrar un error?

Ese mensaje suele aparecer cuando WordPress intenta enviar una redirección (a menudo vía JavaScript/meta refresh) cuando cree que la URL de la petición es incorrecta o la autenticación está incompleta. El navegador entonces golpea la siguiente URL y el ciclo se repite.

2) ¿Siempre lo causa SSL?

No. El desajuste SSL/proxy es común, pero problemas de scope de cookies (dominio/path/secure flag), redirecciones cacheadas y reglas conflictivas www/non-www son igual de frecuentes. El discriminador más rápido es la cadena de redirecciones: cambios de esquema sugieren SSL; rebotes entre login/admin sugieren cookies.

3) ¿Debo arreglarlo definiendo WP_HOME y WP_SITEURL en wp-config.php?

A veces. Es un plano de control válido, especialmente si quieres config-as-code. Pero no lo mezcles casualmente con valores gestionados en BD; los overrides pueden confundir a tu yo futuro. Si los pones en wp-config.php, quita la tentación de “cambiarlo desde la UI”.

4) Estoy detrás de un load balancer. ¿Qué cabeceras deben ser correctas?

Como mínimo: preservar Host y pasar X-Forwarded-Proto reflejando el esquema del cliente. También pasa X-Forwarded-For para logging/rate-limits. Luego asegúrate de que WordPress/PHP confíen en esas cabeceras sólo desde IPs de proxy conocidas.

5) ¿Por qué funciona para mí pero no para otros usuarios?

Suele ser caché. Un POP del CDN puede haber cacheado un 301/302 malo; o un navegador cacheó un 301; o una ruta específica está cacheada con Set-Cookie eliminado. Purga caches de borde y verifica Cache-Control en respuestas de redirección.

6) ¿Cómo sé si las cookies son el problema?

Si el login “tiene éxito” pero vuelves a wp-login.php, casi siempre son cookies. Confírmalo capturando Set-Cookie y asegurando que la cookie se devuelve en la siguiente petición (curl cookie jar, o cabeceras de la pestaña Network en devtools).

7) ¿Puede un plugin causar bucles de redirección?

Sí, especialmente plugins de seguridad/SSL/SEO. Pero trata de culpar a un plugin como último paso después de confirmar que la infraestructura no está mintiendo sobre el esquema/host. Desactiva plugins sólo tras capturar la cadena de redirección y comprobar home/siteurl y cabeceras de proxy.

8) ¿Y multisite—las soluciones son diferentes?

Multisite añade más formas de equivocarse con dominio/scope de cookies. Home/siteurl puede no contar toda la historia, el mapeo de dominios añade complejidad y el dominio/path de cookies puede variar por sitio. Abórdalo igual: observa redirecciones y cookies, pero valida hostnames por sitio y ajustes de la red.

9) Arreglé el origen pero los navegadores siguen en bucle. ¿Por qué?

Los navegadores cachean 301 agresivamente. Los CDNs también cachean redirecciones si se les indica. Prueba con un cliente limpio, purga caches y considera usar 302 mientras estabilizas una migración, y luego cambiar a 301 cuando estés seguro.

10) ¿Existe una arquitectura “mejor” para prevenir esto?

Sí: HTTPS de extremo a extremo, un único propietario de redirecciones canónicas (normalmente el borde), cabeceras forwarded correctas y reglas explícitas de no-cache para auth/admin. No es emocionante. Por eso funciona.

Conclusión: próximos pasos que no te hagan perder la tarde

Si sólo adoptas un hábito operativo de esto: siempre captura la cadena de redirección y el comportamiento de las cookies antes de cambiar nada. Los bucles de redirección parecen caóticos, pero son deterministas. El sistema hace exactamente lo que le ordenaste—simplemente no lo que querías.

Pasos prácticos:

  1. Ejecuta las comprobaciones de cadena de redirección con curl y clasifica el bucle (esquema/host vs cookie).
  2. Alinea home/siteurl de WordPress con la URL pública canónica y elimina overrides en conflicto.
  3. Arregla cabeceras proxy y límites de confianza para que el origen conozca esquema y host del cliente.
  4. Haz que una sola capa sea la propietaria de redirecciones canónicas; deshabilita el resto.
  5. Excluye login/admin de todas las capas de caché, luego purga redirecciones cacheadas.
  6. Añade una pequeña prueba de regresión de redirecciones a los despliegues para que esto sea un problema resuelto, no una reunión recurrente.
← Anterior
Debian/Ubuntu: «Funciona en LAN, falla en WAN» — comprobaciones de enrutamiento/NAT que revelan la causa (caso #85)
Siguiente →
Búsquedas DNS lentas en Linux: solucione systemd-resolved correctamente

Deja un comentario