Comment résoudre l’erreur 429 Too Many Requests
L’erreur 429 Too Many Requests est un code de statut HTTP défini dans la RFC 6585 qui signale qu’un client a dépassé la limite de débit imposée par le serveur ou un proxy intermédiaire. Le serveur refuse les requêtes supplémentaires jusqu’à la réinitialisation de la fenêtre de limitation de débit, en renvoyant éventuellement un en-tête Retry-After indiquant combien de temps le client doit attendre.
Contrairement à une erreur 503 Service Unavailable, qui reflète une défaillance de capacité côté serveur, une erreur 429 est un rejet délibéré, dicté par une politique. Comprendre cette distinction est essentiel : la solution ne consiste pas toujours à faire évoluer l’infrastructure — il s’agit d’identifier *qui* envoie trop de requêtes, *pourquoi*, puis de corriger le comportement au bon niveau de la pile.
Ce qui cause réellement une erreur 429
L’erreur apparaît à plusieurs niveaux, et les confondre mène à un mauvais diagnostic. La cause profonde appartient à l’une des quatre catégories suivantes :
- Limitation de débit côté serveur — Les serveurs web (Apache, Nginx), les proxys inverses (HAProxy, Varnish) ou les nœuds de périphérie CDN (Cloudflare, Fastly) appliquent des seuils de requêtes par IP ou par jeton.
- Limitation au niveau de la couche applicative — Les plugins WordPress, les middlewares personnalisés ou les passerelles API imposent leurs propres limites indépendamment du serveur web.
- Épuisement du quota d’API tierce — Votre application appelle une API externe (Google Maps, Stripe, OpenAI) plus rapidement que le quota du fournisseur ne le permet, et l’erreur 429 se propage jusqu’à l’utilisateur final.
- Trafic automatisé malveillant ou non contrôlé — Les tentatives de connexion par force brute, les scrapers agressifs, les scripts de surveillance mal configurés ou les crawlers mal écrits saturent les budgets de requêtes.
Un cas limite souvent négligé : les environnements d’hébergement mutualisé où le pic de trafic d’un locataire voisin consomme les pools de connexions partagées, entraînant la réception par votre application de réponses 429 d’un équilibreur de charge en amont, même si votre propre code se comporte correctement. Si vous êtes sur un plan d’Hébergement Web Mutualisé et que vous observez des pics de 429 intermittents sans pic correspondant dans votre propre trafic, c’est la première hypothèse à tester.
Étape 1 : Identifier la source des requêtes excessives
Corriger une erreur 429 sans en identifier l’origine relève de la conjecture. Commencez par les données.
Lecture des journaux d’accès Apache
grep " 429 " /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20Cette commande extrait chaque réponse 429, compte les occurrences par adresse IP et les classe. Une IP apparaissant des milliers de fois en quelques minutes est soit un bot, soit un script mal configuré, soit un attaquant.
Lecture des journaux d’accès Nginx
awk '$9 == 429 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20Corrélation avec les chemins de requêtes
grep " 429 " /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20Si /wp-login.php ou /xmlrpc.php domine la sortie, vous faites face à une campagne de force brute ou de credential stuffing. Si un endpoint API comme /api/v1/search arrive en tête, le coupable est probablement un client mal configuré ou un scraper.
Utilisation de fail2ban pour identifier les patterns
fail2ban-client status
fail2ban-client status nginx-req-limitSi fail2ban est configuré avec un jail nginx-req-limit, il vous montrera exactement quelles IP ont été bannies en raison de violations de limite de débit, ce qui permet d’économiser un temps considérable d’analyse des journaux.
Étape 2 : Configurer la limitation de débit au niveau du serveur web
Apache : Utilisation de mod_ratelimit et mod_evasive
L’extrait .htaccess couramment diffusé en ligne utilise mod_rewrite pour renvoyer un 403, et non un 429 approprié. Une approche plus sémantiquement correcte et opérationnellement solide utilise mod_evasive pour la mitigation DoS.
Installez et configurez mod_evasive sur Debian/Ubuntu :
apt install libapache2-mod-evasive
a2enmod evasivePuis ajoutez à votre hôte virtuel Apache ou à la configuration globale :
<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>Cela bloque toute IP qui accède à la même page plus de 5 fois par seconde, ou à l’ensemble du site plus de 50 fois par seconde, pendant une période de refroidissement de 10 secondes.
Pour une réponse 429 appropriée via .htaccess sur Apache avec mod_rewrite, vous avez besoin d’un document d’erreur personnalisé :
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 avec gestion correcte des rafales
Le module ngx_http_limit_req_module de Nginx est l’un des outils de limitation de débit les plus efficaces disponibles. Les paramètres clés souvent mal configurés sont burst et nodelay.
Dans /etc/nginx/nginx.conf ou un fichier d’inclusion dédié :
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;
}
}
}Nuance critique : Sans limit_req_status 429, Nginx renvoie par défaut un 503 pour les requêtes soumises à une limitation de débit. Le définir à 429 est sémantiquement correct et permet aux clients d’implémenter une logique de backoff Retry-After appropriée.
nodelay vs. sans indicateur :
- Sans
nodelay: les requêtes excédentaires sont mises en file d’attente et servies avec un délai supplémentaire, consommant des connexions worker. - Avec
nodelay: les requêtes excédentaires au-delà de la rafale sont immédiatement rejetées avec un 429, libérant les ressources plus rapidement. Utiliseznodelaypour les endpoints de connexion et les API publiques.
Ajout d’un en-tête Retry-After
Les clients qui respectent la RFC 6585 honoreront un en-tête Retry-After. Dans Nginx, ajoutez-le à la réponse d’erreur :
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
add_header Retry-After 60 always;
}Étape 3 : Diagnostiquer et corriger les conflits de plugins WordPress
WordPress est une source courante d’erreurs 429 auto-infligées. Les plugins qui interrogent des API externes à chaque chargement de page — outils SEO récupérant des données de mots-clés, plugins d’analyse appelant leur serveur, ou extensions WooCommerce interrogeant des passerelles de paiement — peuvent rapidement épuiser les limites de débit.
Procédure d’isolation systématique :
- Désactivez tous les plugins via le tableau de bord WordPress ou, si le tableau de bord est inaccessible, via WP-CLI :
wp plugin deactivate --all- Réactivez les plugins un par un, en testant après chaque activation :
wp plugin activate plugin-slug- Surveillez le journal d’accès dans un terminal séparé pendant la réactivation :
tail -f /var/log/nginx/access.log | grep " 429 "- Une fois le plugin fautif identifié, vérifiez ses paramètres pour les intervalles d’interrogation API ou les options de fréquence de requêtes avant de le désactiver définitivement.
Coupables courants : Jetpack (modules de statistiques et de synchronisation), Yoast SEO (lorsque connecté à MyYoast), WooCommerce Subscriptions, et tout plugin utilisant wp_remote_get() intégré à WordPress dans une boucle sans mise en cache par transient.
La bonne solution n’est presque jamais de supprimer le plugin — il s’agit de s’assurer que les réponses API sont mises en cache à l’aide des transients 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;
}Étape 4 : Implémenter la limitation de débit des requêtes API dans le code applicatif
Lorsque votre application est le *client* qui appelle une API tierce, vous êtes responsable du respect de leurs limites de débit. Se fier à la capture réactive des réponses 429 est une mauvaise pratique d’ingénierie — implémentez une limitation proactive.
Node.js avec 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 avec tenacity pour le backoff exponentiel
La limitation seule est insuffisante si l’API impose des limites de rafale. Combinez la limitation avec un backoff exponentiel sur les réponses 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()Cela effectue jusqu’à 5 tentatives avec un backoff exponentiel (2s, 4s, 8s, 16s, 32s), plafonné à 60 secondes — un pattern qui respecte l’infrastructure du fournisseur d’API tout en récupérant de manière élégante.
Respect de l’en-tête Retry-After
Si l’API renvoie un en-tête Retry-After, utilisez-le plutôt qu’un backoff fixe :
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()Étape 5 : Bloquer et gérer les bots à plusieurs niveaux
Les bots s’annoncent rarement honnêtement, mais ils laissent des empreintes dans les chaînes user-agent, les patterns de requêtes et les anomalies d’en-têtes.
Bloquer les bots malveillants connus dans 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;
}
}Gérer le taux de crawl via robots.txt
User-agent: Googlebot
Crawl-delay: 2
User-agent: *
Crawl-delay: 10Notez que Crawl-delay n’est pas respecté par tous les crawlers, mais il signale l’intention et est respecté par Bing, Yandex et la plupart des bots bien configurés.
Intégration d’un pare-feu applicatif web (WAF)
Un WAF opérant au niveau de la périphérie CDN (Cloudflare, AWS WAF, Sucuri) peut appliquer des limites de débit avant que le trafic n’atteigne votre serveur d’origine, réduisant considérablement la charge. Les règles de limitation de débit de Cloudflare, par exemple, peuvent être configurées pour défier ou bloquer les IP dépassant un seuil sans aucune modification de la configuration de votre serveur d’origine — un avantage opérationnel significatif pour les sites à fort trafic.
Étape 6 : Ajuster les paramètres des plugins de sécurité dans WordPress
Si vous utilisez Wordfence, les seuils de limitation de débit sont souvent définis de manière conservatrice et peuvent déclencher des faux positifs pour des utilisateurs légitimes, notamment sur les sites avec une utilisation intensive d’AJAX ou une activité importante d’utilisateurs connectés.
Accédez à Wordfence > Firewall > All Firewall Options > Rate Limiting et vérifiez :
- How should we treat Google’s crawlers — définissez sur « Verified Google crawlers are not rate limited » pour éviter un impact sur le SEO.
- If anyone’s requests exceed — augmentez le seuil par rapport à la valeur par défaut (par exemple, de 240 à 480 requêtes par minute pour les utilisateurs connectés sur des sites à contenu dense).
- If a crawler’s page views exceed — ajustez en fonction de vos besoins réels en budget de crawl.
Après l’ajustement, surveillez la vue Live Traffic de Wordfence pendant 24 à 48 heures pour confirmer que les utilisateurs légitimes ne sont plus bloqués.
Étape 7 : Vider le cache côté client et diagnostiquer les problèmes au niveau du navigateur
Une réponse 429 mise en cache dans le navigateur est rare mais possible si la réponse incluait des en-têtes Cache-Control: max-age (une mauvaise configuration du serveur). Les réponses 429 standard ne devraient pas être mises en cache.
Chrome :
Settings > Privacy and Security > Clear browsing dataSélectionnez Cached images and files et Cookies and other site data, puis effacez.
Vérifiez les en-têtes de réponse directement en utilisant curl pour exclure un comportement spécifique au navigateur :
curl -I -X GET https://yourdomain.com/problematic-endpointRecherchez les en-têtes Cache-Control, Retry-After et X-RateLimit-* dans la réponse. Ces en-têtes révèlent exactement quel niveau applique la limite et quand le client peut réessayer.
Comparaison : Approches de limitation de débit par niveau
| Niveau | Outil / Méthode | Granularité | Surcharge | Idéal pour |
|---|
| — | — | — | — | — |
|---|
| CDN / Périphérie | Cloudflare Rate Limiting, AWS WAF | Par IP, par chemin, par en-tête | Très faible (pré-origine) | DDoS, mitigation de scrapers |
|---|
| Proxy inverse | Nginx `limit_req_zone` | Par IP, par zone | Faible | Endpoints API, pages de connexion |
|---|
| Serveur web | Apache `mod_evasive` | Par IP, par page | Faible à moyen | Hébergement mutualisé, stacks legacy |
|---|
| Application | Middleware throttle, passerelle API | Par utilisateur, par jeton, par clé | Moyen | SaaS multi-locataires, REST APIs |
|---|
| Plugin CMS | Wordfence, iThemes Security | Par IP, par rôle utilisateur | Moyen à élevé | Protection spécifique à WordPress |
|---|
| Code client | `tenacity`, `p-throttle`, backoff | Par requête sortante | Côté application | Consommation d’API tierces |
|---|
Quand contacter votre hébergeur
Escaladez vers votre hébergeur lorsque :
- L’erreur 429 provient d’un équilibreur de charge en amont ou d’un proxy inverse que vous ne contrôlez pas.
- L’analyse des journaux montre que votre application est bien dans les volumes de requêtes attendus, mais l’erreur persiste.
- Vous avez besoin d’une exemption temporaire de limite de débit lors d’un pic de trafic planifié (lancement de produit, campagne marketing).
- L’erreur n’apparaît que dans des régions géographiques spécifiques, suggérant des problèmes de CDN ou de routage anycast.
Lorsque vous utilisez un plan d’Hébergement VPS, vous avez un accès direct aux fichiers de configuration du serveur et pouvez implémenter toutes les modifications Nginx et Apache décrites ci-dessus sans ouvrir un ticket de support. Sur une infrastructure gérée comme les Serveurs Dédiés, l’équipe de support de votre fournisseur peut vous aider avec le suivi des connexions au niveau du noyau et les règles de pare-feu matériel qui vont au-delà de ce que la configuration au niveau applicatif peut accomplir.
Si votre stack inclut un panneau de contrôle, le VPS avec cPanel expose les paramètres ModSecurity et de limitation de débit Apache via une interface graphique, ce qui simplifie la configuration pour les équipes sans expertise approfondie en ligne de commande.
Sécurisation des endpoints API avec SSL
Un facteur souvent négligé : les endpoints HTTP non chiffrés sont plus susceptibles aux attaques par rejeu et au credential stuffing, qui provoquent des erreurs 429 induites par la force brute. L’application du HTTPS avec un Certificat SSL valide garantit que les jetons d’authentification et les cookies de session ne peuvent pas être interceptés et rejoués par des outils automatisés, réduisant à la source une catégorie de trafic déclencheur de limitation de débit.
Matrice de décision technique : Choisir la bonne solution
Utilisez cette liste de contrôle pour orienter votre diagnostic vers la solution correcte :
- 429 sur
/wp-login.phpou/xmlrpc.php— Renforcez Nginxlimit_reqpour ces chemins, bloquezxmlrpc.phpentièrement si non nécessaire, activez la protection contre la force brute de Wordfence. - 429 sur les endpoints API depuis votre propre code applicatif — Implémentez un backoff exponentiel avec analyse de l’en-tête
Retry-After; ajoutez une mise en cache transient/Redis pour réduire la fréquence des appels sortants. - 429 affectant tous les utilisateurs de manière intermittente sur un hébergement mutualisé — Migrez vers un VPS pour des ressources isolées et des limites de débit configurables.
- 429 provenant d’une API tierce consommée par votre application — Auditez la fréquence des appels, implémentez une file d’attente de requêtes, mettez agressivement en cache les réponses, et contactez le fournisseur d’API pour discuter d’augmentations de quota.
- 429 causé par un bot ou crawler spécifique — Bloquez au niveau WAF ou Nginx
mappar user-agent ; vérifiez les crawlers légitimes (Googlebot) via DNS inverse avant de bloquer. - 429 apparaissant uniquement dans le navigateur, pas dans
curl— Videz le cache du navigateur ; vérifiez si un service worker met en cache la réponse d’erreur ; inspectez les en-têtesCache-Controlsur la réponse 429. - 429 sans pattern identifiable dans les journaux — Vérifiez les journaux du CDN en amont ou de l’équilibreur de charge ; la limite peut être appliquée à un niveau d’infrastructure non visible dans les journaux applicatifs.
FAQ
Quelle est la différence entre une erreur 429 et une erreur 503 ?
Une erreur 429 est un rejet délibéré, dicté par une politique, émis lorsqu’un client dépasse un taux de requêtes défini. Une erreur 503 indique que le serveur est temporairement incapable de traiter les requêtes en raison d’une surcharge ou d’une maintenance. La solution pour une erreur 429 est l’ajustement de la limite de débit ou la correction du comportement du client ; la solution pour une erreur 503 est la mise à l’échelle de la capacité ou la récupération du service.
Dois-je toujours augmenter les limites de débit lorsque je vois une erreur 429 ?
Non. Augmenter les limites n’est approprié que lorsque du trafic légitime est bloqué. Si l’erreur 429 est causée par des bots, des tentatives de force brute ou un script mal configuré, augmenter la limite aggrave le problème en laissant passer davantage de trafic malveillant. Identifiez toujours la source en premier.
Que fait l’en-tête Retry-After et dois-je toujours l’inclure ?
L’en-tête Retry-After indique au client combien de secondes attendre avant de réessayer. La RFC 6585 recommande de l’inclure avec chaque réponse 429. Les clients HTTP et les consommateurs d’API bien configurés le respecteront, réduisant les tempêtes de nouvelles tentatives qui aggravent le problème de limitation de débit initial.
Une erreur 429 peut-elle nuire à mon SEO ?
Oui, si Googlebot reçoit des réponses 429 de manière constante, il réduira la fréquence de crawl de votre site, ce qui peut retarder l’indexation des contenus nouveaux ou mis à jour. Wordfence et les plugins similaires doivent être configurés pour exempter les crawlers Google vérifiés de la limitation de débit. Surveillez le rapport Crawl Stats de Google Search Console pour détecter les pics d’erreurs serveur.
Comment empêcher ma propre application de déclencher des erreurs 429 sur des API externes ?
Implémentez une combinaison de limitation proactive (limitez le taux de requêtes sortantes en dessous du seuil documenté de l’API), de mise en cache agressive des réponses (stockez les résultats d’API dans Redis ou Memcached avec des TTL appropriés), et de backoff exponentiel réactif (analysez les en-têtes Retry-After et effectuez un backoff en conséquence). Ne faites jamais d’appels API de manière synchrone à chaque chargement de page sans une couche de mise en cache devant eux.
