Cómo resolver el error 429 Too Many Requests
El error 429 Too Many Requests es un código de estado HTTP definido en RFC 6585 que indica que un cliente ha superado el límite de velocidad impuesto por el servidor o un proxy intermediario. El servidor rechaza más solicitudes hasta que se restablece la ventana de limitación de velocidad, devolviendo opcionalmente un encabezado Retry-After que indica cuánto tiempo debe esperar el cliente.
A diferencia de un 503 Service Unavailable, que refleja un fallo de capacidad del lado del servidor, un 429 es un rechazo deliberado basado en políticas. Comprender esa distinción es fundamental: la solución no siempre consiste en escalar la infraestructura, sino en identificar *quién* está enviando demasiadas solicitudes, *por qué*, y luego corregir el comportamiento en la capa correcta del stack.
Qué Causa Realmente un Error 429
El error aparece en múltiples capas, y confundirlas lleva a un diagnóstico erróneo. La causa raíz se divide en una de cuatro categorías:
- Limitación de velocidad del lado del servidor — Los servidores web (Apache, Nginx), proxies inversos (HAProxy, Varnish) o nodos de borde CDN (Cloudflare, Fastly) aplican umbrales de solicitudes por IP o por token.
- Limitación a nivel de aplicación — Los plugins de WordPress, middleware personalizado o API gateways imponen sus propios límites independientemente del servidor web.
- Agotamiento de cuota de API de terceros — Tu aplicación llama a una API externa (Google Maps, Stripe, OpenAI) más rápido de lo que permite la cuota del proveedor, y el 429 se propaga de vuelta al usuario final.
- Tráfico automatizado malicioso o no controlado — Intentos de inicio de sesión por fuerza bruta, scrapers agresivos, scripts de monitoreo mal configurados o crawlers mal escritos saturan los presupuestos de solicitudes.
Un caso límite que se pasa por alto con frecuencia: entornos de hosting compartido donde el pico de tráfico de un inquilino vecino consume grupos de conexiones compartidas, haciendo que tu aplicación reciba respuestas 429 de un balanceador de carga upstream aunque tu propio código funcione correctamente. Si estás en un plan de Hosting Web Compartido y ves ráfagas intermitentes de 429 sin un pico correspondiente en tu propio tráfico, esta es la primera hipótesis a comprobar.
Paso 1: Identificar el Origen de las Solicitudes Excesivas
Corregir un 429 sin identificar su origen es adivinar. Comienza con los datos.
Lectura de Registros de Acceso de Apache
grep " 429 " /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20Este comando extrae cada respuesta 429, cuenta las ocurrencias por dirección IP y las clasifica. Una IP que aparece miles de veces en minutos es un bot, un script mal configurado o un atacante.
Lectura de Registros de Acceso de Nginx
awk '$9 == 429 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20Correlación con Rutas de Solicitud
grep " 429 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20Si /wp-login.php o /xmlrpc.php domina la salida, estás lidiando con una campaña de fuerza bruta o relleno de credenciales. Si un endpoint de API como /api/v1/search encabeza la lista, el culpable probablemente sea un cliente mal configurado o un scraper.
Uso de fail2ban para Detectar Patrones
fail2ban-client status
fail2ban-client status nginx-req-limitSi fail2ban está configurado con una jaula nginx-req-limit, te mostrará exactamente qué IPs han sido bloqueadas debido a violaciones del límite de velocidad, ahorrando un tiempo considerable en el análisis de registros.
Paso 2: Configurar la Limitación de Velocidad a Nivel del Servidor Web
Apache: Uso de mod_ratelimit y mod_evasive
El fragmento .htaccess que circula habitualmente en línea usa mod_rewrite para devolver un 403, no un 429 correcto. Un enfoque más semánticamente correcto y operativamente sólido usa mod_evasive para la mitigación de DoS.
Instala y configura mod_evasive en Debian/Ubuntu:
apt install libapache2-mod-evasive
a2enmod evasiveLuego añade a tu host virtual de Apache o configuración global:
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSEmailNotify admin@yourdomain.com
DOSLogDir /var/log/mod_evasive
</IfModule>Esto bloquea cualquier IP que acceda a la misma página más de 5 veces por segundo, o al sitio completo más de 50 veces por segundo, durante un período de enfriamiento de 10 segundos.
Para una respuesta 429 correcta mediante .htaccess en Apache con mod_rewrite, necesitas un documento de error personalizado:
ErrorDocument 429 "Too Many Requests"
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.*(SemrushBot|AhrefsBot|MJ12bot|DotBot).*$ [NC]
RewriteRule .* - [R=429,L]
</IfModule>Nginx: limit_req_zone con Manejo Correcto de Ráfagas
El módulo ngx_http_limit_req_module de Nginx es una de las herramientas de limitación de velocidad más efectivas disponibles. Los parámetros clave que se configuran incorrectamente con frecuencia son burst y nodelay.
En /etc/nginx/nginx.conf o en un archivo de inclusión dedicado:
http {
# Zone keyed by client IP, 10MB shared memory, 10 requests/second baseline
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
# Return 429 instead of the default 503
limit_req_status 429;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
}
location /wp-login.php {
limit_req zone=login_limit burst=3 nodelay;
}
}
}Matiz crítico: Sin limit_req_status 429, Nginx devuelve un 503 para las solicitudes con límite de velocidad de forma predeterminada. Configurarlo en 429 es semánticamente correcto y permite a los clientes implementar una lógica de retroceso Retry-After adecuada.
nodelay vs. sin indicador:
- Sin
nodelay: las solicitudes excedentes se ponen en cola y se sirven con retraso añadido, consumiendo conexiones de trabajadores. - Con
nodelay: las solicitudes excedentes más allá de la ráfaga se rechazan inmediatamente con un 429, liberando recursos más rápido. Usanodelaypara endpoints de inicio de sesión y APIs públicas.
Añadir un Encabezado Retry-After
Los clientes que respetan RFC 6585 respetarán un encabezado Retry-After. En Nginx, añádelo a la respuesta de error:
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
add_header Retry-After 60 always;
}Paso 3: Diagnosticar y Corregir Conflictos de Plugins de WordPress
WordPress es una fuente común de errores 429 autoinfligidos. Los plugins que consultan APIs externas en cada carga de página — herramientas SEO que obtienen datos de palabras clave, plugins de análisis que se conectan a casa, o extensiones de WooCommerce que consultan pasarelas de pago — pueden agotar los límites de velocidad rápidamente.
Procedimiento de aislamiento sistemático:
- Desactiva todos los plugins desde el panel de WordPress o, si el panel no está accesible, mediante WP-CLI:
wp plugin deactivate --all- Reactiva los plugins uno a uno, probando después de cada activación:
wp plugin activate plugin-slug- Monitorea el registro de acceso en un terminal separado mientras reactivas:
tail -f /var/log/nginx/access.log | grep " 429 "- Una vez identificado el plugin problemático, revisa su configuración para ver las opciones de intervalos de consulta a la API o frecuencia de solicitudes antes de desactivarlo permanentemente.
Infractores comunes: Jetpack (módulos de estadísticas y sincronización), Yoast SEO (cuando está conectado a MyYoast), WooCommerce Subscriptions, y cualquier plugin que use wp_remote_get() integrado de WordPress en un bucle sin caché transitoria.
La solución correcta casi nunca es eliminar el plugin — es asegurarse de que las respuestas de la API se almacenen en caché usando transitorios de WordPress:
$cached = get_transient( 'my_api_response' );
if ( false === $cached ) {
$response = wp_remote_get( 'https://api.example.com/data' );
set_transient( 'my_api_response', $response, HOUR_IN_SECONDS );
$cached = $response;
}Paso 4: Implementar Limitación de Solicitudes a la API en el Código de la Aplicación
Cuando tu aplicación es el *cliente* que accede a una API de terceros, eres responsable de respetar sus límites de velocidad. Depender de capturar respuestas 429 de forma reactiva es una mala práctica de ingeniería — implementa una limitación proactiva.
Node.js con p-throttle
import pThrottle from 'p-throttle';
const throttle = pThrottle({
limit: 10, // max 10 calls
interval: 1000 // per 1000ms (1 second)
});
const throttledFetch = throttle(async (url) => {
const response = await fetch(url);
return response.json();
});Python con tenacity para Retroceso Exponencial
La limitación por sí sola es insuficiente si la API impone límites de ráfaga. Combina la limitación con retroceso exponencial en respuestas 429:
import requests
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception
def is_rate_limited(exception):
return (
isinstance(exception, requests.HTTPError)
and exception.response.status_code == 429
)
@retry(
retry=retry_if_exception(is_rate_limited),
wait=wait_exponential(multiplier=1, min=2, max=60),
stop=stop_after_attempt(5)
)
def call_api(url):
response = requests.get(url)
response.raise_for_status()
return response.json()Esto reintenta hasta 5 veces con retroceso exponencial (2s, 4s, 8s, 16s, 32s), con un máximo de 60 segundos — un patrón que respeta la infraestructura del proveedor de la API mientras se recupera de forma elegante.
Respeto del Encabezado Retry-After
Si la API devuelve un encabezado Retry-After, úsalo en lugar de un retroceso fijo:
def call_with_retry_after(url):
response = requests.get(url)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 5))
time.sleep(retry_after)
return call_with_retry_after(url)
response.raise_for_status()
return response.json()Paso 5: Bloquear y Gestionar Bots en Múltiples Capas
Los bots rara vez se anuncian honestamente, pero sí dejan huellas en cadenas de agente de usuario, patrones de solicitud y anomalías de encabezado.
Bloquear Bots Maliciosos Conocidos en Nginx
map $http_user_agent $bad_bot {
default 0;
~*SemrushBot 1;
~*AhrefsBot 1;
~*MJ12bot 1;
~*DotBot 1;
~*PetalBot 1;
~*serpstatbot 1;
}
server {
if ($bad_bot) {
return 429;
}
}Gestionar la Velocidad de Rastreo mediante robots.txt
User-agent: Googlebot
Crawl-delay: 2
User-agent: *
Crawl-delay: 10Ten en cuenta que Crawl-delay no es respetado por todos los crawlers, pero señala la intención y es respetado por Bing, Yandex y la mayoría de los bots bien configurados.
Integración con Firewall de Aplicaciones Web (WAF)
Un WAF que opera en el borde CDN (Cloudflare, AWS WAF, Sucuri) puede aplicar límites de velocidad antes de que el tráfico llegue a tu servidor de origen, reduciendo drásticamente la carga. Las reglas de limitación de velocidad de Cloudflare, por ejemplo, pueden configurarse para desafiar o bloquear IPs que superen un umbral sin ningún cambio en la configuración de tu servidor de origen — una ventaja operativa significativa para sitios de alto tráfico.
Paso 6: Ajustar la Configuración de Plugins de Seguridad en WordPress
Si usas Wordfence, los umbrales de limitación de velocidad suelen estar configurados de forma conservadora y pueden generar falsos positivos para usuarios legítimos, especialmente en sitios con uso intensivo de AJAX o actividad de usuarios conectados.
Navega a Wordfence > Firewall > All Firewall Options > Rate Limiting y revisa:
- How should we treat Google’s crawlers — configúralo en “Verified Google crawlers are not rate limited” para evitar impacto en el SEO.
- If anyone’s requests exceed — aumenta el umbral desde el valor predeterminado (por ejemplo, de 240 a 480 solicitudes por minuto para usuarios conectados en sitios con mucho contenido).
- If a crawler’s page views exceed — ajusta según los requisitos reales de tu presupuesto de rastreo.
Después de ajustar, monitorea la vista de Tráfico en Vivo de Wordfence durante 24–48 horas para confirmar que los usuarios legítimos ya no están siendo bloqueados.
Paso 7: Limpiar la Caché del Cliente y Diagnosticar Problemas a Nivel del Navegador
Una respuesta 429 almacenada en caché en el navegador es poco frecuente pero posible si la respuesta incluía encabezados Cache-Control: max-age (una configuración incorrecta del servidor). Las respuestas 429 estándar no deberían almacenarse en caché.
Chrome:
Settings > Privacy and Security > Clear browsing dataSelecciona Cached images and files y Cookies and other site data, luego limpia.
Verifica los encabezados de respuesta directamente usando curl para descartar comportamientos específicos del navegador:
curl -I -X GET https://yourdomain.com/problematic-endpointBusca los encabezados Cache-Control, Retry-After y X-RateLimit-* en la respuesta. Estos encabezados revelan exactamente qué capa está aplicando el límite y cuándo puede reintentar el cliente.
Comparación: Enfoques de Limitación de Velocidad por Capa
| Capa | Herramienta / Método | Granularidad | Sobrecarga | Mejor Para |
|---|
| — | — | — | — | — |
|---|
| CDN / Borde | Cloudflare Rate Limiting, AWS WAF | Por IP, por ruta, por encabezado | Muy baja (pre-origen) | DDoS, mitigación de scrapers |
|---|
| Proxy Inverso | Nginx `limit_req_zone` | Por IP, por zona | Baja | Endpoints de API, páginas de inicio de sesión |
|---|
| Servidor Web | Apache `mod_evasive` | Por IP, por página | Baja-media | Hosting compartido, stacks heredados |
|---|
| Aplicación | Middleware throttle, API gateway | Por usuario, por token, por clave | Media | SaaS multi-inquilino, REST APIs |
|---|
| Plugin CMS | Wordfence, iThemes Security | Por IP, por rol de usuario | Media-alta | Protección específica para WordPress |
|---|
| Código Cliente | `tenacity`, `p-throttle`, retroceso | Por solicitud saliente | Del lado de la aplicación | Consumo de APIs de terceros |
|---|
Cuándo Contactar a Tu Proveedor de Hosting
Escala a tu proveedor de hosting cuando:
- El 429 se origina en un balanceador de carga upstream o proxy inverso que no controlas.
- El análisis de registros muestra que tu aplicación está dentro de los volúmenes de solicitudes esperados pero el error persiste.
- Necesitas una exención temporal del límite de velocidad durante un pico de tráfico planificado (lanzamiento de producto, campaña de marketing).
- El error aparece solo en regiones geográficas específicas, lo que sugiere problemas de enrutamiento CDN o anycast.
Al ejecutar en un plan de Hosting VPS, tienes acceso directo a los archivos de configuración del servidor y puedes implementar todos los cambios de Nginx y Apache descritos anteriormente sin abrir un ticket de soporte. En infraestructura gestionada como Servidores Dedicados, el equipo de soporte de tu proveedor puede ayudar con el seguimiento de conexiones a nivel de kernel y reglas de firewall de hardware que van más allá de lo que puede lograr la configuración a nivel de aplicación.
Si tu stack incluye un panel de control, VPS con cPanel expone la configuración de ModSecurity y la limitación de velocidad de Apache a través de una interfaz gráfica, lo que simplifica la configuración para equipos sin experiencia profunda en línea de comandos.
Protección de Endpoints de API con SSL
Un factor que se pasa por alto con frecuencia: los endpoints HTTP sin cifrar son más susceptibles a ataques de repetición y relleno de credenciales, que provocan errores 429 inducidos por fuerza bruta. Aplicar HTTPS con un Certificado SSL válido garantiza que los tokens de autenticación y las cookies de sesión no puedan ser interceptados y reproducidos por herramientas automatizadas, reduciendo una categoría de tráfico que desencadena límites de velocidad desde su origen.
Matriz de Decisión Técnica: Elegir la Solución Correcta
Usa esta lista de verificación para dirigir tu diagnóstico a la solución correcta:
- 429 en
/wp-login.phpo/xmlrpc.php— Refuerza Nginxlimit_reqpara esas rutas, bloqueaxmlrpc.phpcompletamente si no es necesario, activa la protección contra fuerza bruta de Wordfence. - 429 en endpoints de API desde tu propio código de aplicación — Implementa retroceso exponencial con análisis del encabezado
Retry-After; añade caché transitoria/Redis para reducir la frecuencia de llamadas salientes. - 429 que afecta a todos los usuarios de forma intermitente en hosting compartido — Migra a un VPS para recursos aislados y límites de velocidad configurables.
- 429 de una API de terceros que consume tu aplicación — Audita la frecuencia de llamadas, implementa colas de solicitudes, almacena respuestas en caché de forma agresiva y contacta al proveedor de la API para discutir aumentos de cuota.
- 429 causado por un bot o crawler específico — Bloquea en el nivel WAF o Nginx
mappor agente de usuario; verifica los crawlers legítimos (Googlebot) mediante DNS inverso antes de bloquear. - 429 que aparece solo en el navegador, no en
curl— Limpia la caché del navegador; comprueba si hay un service worker almacenando en caché la respuesta de error; inspecciona los encabezadosCache-Controlen la respuesta 429. - 429 sin ningún patrón identificable en los registros — Revisa los registros del CDN upstream o del balanceador de carga; el límite puede estar aplicándose en una capa de infraestructura no visible en los registros de la aplicación.
Preguntas Frecuentes
¿Cuál es la diferencia entre un error 429 y un 503?
Un 429 es un rechazo deliberado basado en políticas que se emite cuando un cliente supera una tasa de solicitudes definida. Un 503 indica que el servidor no puede manejar temporalmente las solicitudes debido a sobrecarga o mantenimiento. La solución para un 429 es el ajuste del límite de velocidad o la corrección del comportamiento del cliente; la solución para un 503 es el escalado de capacidad o la recuperación del servicio.
¿Debo siempre aumentar los límites de velocidad cuando veo un 429?
No. Aumentar los límites solo es apropiado cuando se está bloqueando tráfico legítimo. Si el 429 es causado por bots, intentos de fuerza bruta o un script mal configurado, aumentar el límite empeora el problema al permitir más tráfico malicioso. Identifica siempre el origen primero.
¿Qué hace el encabezado Retry-After y debo incluirlo siempre?
El encabezado Retry-After indica al cliente cuántos segundos debe esperar antes de reintentar. RFC 6585 recomienda incluirlo con cada respuesta 429. Los clientes HTTP y consumidores de API bien configurados lo respetarán, reduciendo las tormentas de reintentos que agravan el problema original de limitación de velocidad.
¿Puede un error 429 perjudicar mi SEO?
Sí, si Googlebot recibe respuestas 429 de forma consistente, reducirá la frecuencia de rastreo de tu sitio, lo que puede retrasar la indexación de contenido nuevo o actualizado. Wordfence y plugins similares deben configurarse para eximir a los crawlers verificados de Google de la limitación de velocidad. Monitorea el informe de Estadísticas de Rastreo de Google Search Console para detectar picos en errores del servidor.
¿Cómo evito que mi propia aplicación desencadene errores 429 en APIs externas?
Implementa una combinación de limitación proactiva (limita la tasa de solicitudes salientes por debajo del umbral documentado de la API), almacenamiento agresivo en caché de respuestas (guarda los resultados de la API en Redis o Memcached con TTLs apropiados) y retroceso exponencial reactivo (analiza los encabezados Retry-After y retrocede en consecuencia). Nunca realices llamadas a la API de forma síncrona en cada carga de página sin una capa de caché delante de ellas.
