Solucionando ERR_TOO_MANY_REDIRECTS y 400 en Django con Dominio Personalizado (Railway + Cloudflare)

12 abril 2025

Desplegar una aplicación Django/Wagtail en Railway es una experiencia bastante fluida. Sin embargo, al configurar un dominio personalizado a través de Cloudflare, puedes encontrarte con dos errores frustrantes que impiden el acceso a tu sitio: ERR_TOO_MANY_REDIRECTS (Demasiadas Redirecciones) o Bad Request (400) (Solicitud Incorrecta).

Si te has topado con esto, ¡no estás solo! Aquí te explico por qué ocurren y los pasos concretos para solucionarlos.

Problema 1: El Bucle Infinito (ERR_TOO_MANY_REDIRECTS)

Este error suele aparecer si tienes configurado SECURE_SSL_REDIRECT = True en Django (lo cual es bueno para producción) y tu modo SSL/TLS en Cloudflare está en "Flexible".

¿Por qué pasa?

  1. El usuario va a https://tudominio.com.
  2. Cloudflare recibe la conexión HTTPS.
  3. Modo Flexible: Cloudflare se conecta a tu servidor en Railway usando HTTP (no HTTPS).
  4. Tu app Django recibe la solicitud HTTP y, como SECURE_SSL_REDIRECT es True, intenta redirigir al usuario de vuelta a HTTPS.
  5. ¡Bucle! El navegador vuelve al paso 1.

Solución:

Necesitamos que Django confíe en la información que le envía Cloudflare sobre la conexión original y que Cloudflare se comunique de forma segura con Railway.

Paso 1: Configurar Django para Confiar en Proxies

Añade estas líneas a tu archivo settings.py. Le dicen a Django que use los encabezados X-Forwarded-Host y X-Forwarded-Proto que envían los proxies como Cloudflare y Railway:

# settings.py

# ... otras configuraciones ...

# Settings para confiar en los encabezados del proxy (Cloudflare/Railway)
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# ... resto de configuraciones ...

Paso 2: Ajustar Modo SSL/TLS en Cloudflare

  1. Ve a tu panel de Cloudflare -> Tu dominio -> SSL/TLS -> Visión General (Overview).
  2. Cambia el modo SSL/TLS a "Full" o "Full (Strict)".
    • Full: Cloudflare conecta a Railway usando HTTPS (pero no valida el certificado de Railway, generalmente ok).
    • Full (Strict): Cloudflare conecta a Railway usando HTTPS y valida el certificado (más seguro, si Railway provee uno válido).
  3. Importante: Asegúrate de que NO esté en modo "Flexible".

Problema 2: La Puerta Cerrada (Bad Request (400))

Una vez solucionado el bucle, podrías encontrarte con un error 400. Esto casi siempre significa que Django está rechazando la solicitud porque el dominio desde el que se accede (tudominio.com) no está en la lista de hosts permitidos.

Solución:

Paso 1: Actualizar ALLOWED_HOSTS

Django necesita saber qué nombres de host puede servir. Debes añadir tu dominio personalizado a esta configuración. En Railway, esto se hace generalmente a través de las Variables de Entorno:

  1. Ve a tu servicio en Railway -> Variables.
  2. Busca o crea la variable ALLOWED_HOSTS.
  3. Asegúrate de que incluya tu dominio personalizado y el dominio de Railway, separados por comas. Ejemplo: ALLOWED_HOSTS=tudominio.com,tu-app.up.railway.app

Paso 2: Actualizar CSRF_TRUSTED_ORIGINS

Para que las solicitudes seguras (HTTPS) funcionen correctamente (especialmente formularios), añade tu dominio (con https://) a los orígenes de confianza:

  1. Ve a tu servicio en Railway -> Variables.
  2. Busca o crea la variable CSRF_TRUSTED_ORIGINS.
  3. Asegúrate de que incluya tu dominio personalizado con https://, separado por comas. Ejemplo: CSRF_TRUSTED_ORIGINS=https://tudominio.com,https://tu-app.up.railway.app

Conclusión

Configurar correctamente SECURE_PROXY_SSL_HEADER, ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS y el modo SSL/TLS de Cloudflare es esencial cuando tu aplicación Django se ejecuta detrás de un proxy inverso como Cloudflare. Después de realizar estos cambios, no olvides limpiar la caché de tu navegador y purgar la caché de Cloudflare ("Purge Everything") para ver los resultados inmediatamente.

¡Espero que esto ayude a otros a superar estos obstáculos comunes!