TL;DRUne erreur 429 Too Many Requests signifie qu'un serveur, un CDN ou une application trouve que vous lui envoyez trop de requêtes en trop peu de temps. Elle n'est jamais « spontanée » : un réglage précis la déclenche, et savoir lequel est la moitié de la réparation.
Ce que signifie vraiment une erreur 429#
Le code 429 Too Many Requests fait partie des erreurs client (famille 4xx). La RFC 6585 le décrit ainsi : l'utilisateur a envoyé trop de requêtes dans un laps de temps donné. C'est ce qu'on appelle la limitation de débit (rate limiting).
Deux précisions importantes, qui expliquent pourquoi le même code recouvre des situations très différentes :
- La spécification ne dit pas comment le serveur identifie l'utilisateur ni comment il compte les requêtes. Selon la documentation MDN, la limite se base le plus souvent sur l'adresse IP du client, mais peut aussi être propre à un compte ou à une application si la requête est authentifiée ou porte un cookie.
- Le serveur peut ajouter un en-tête
Retry-Afterqui indique combien de temps attendre avant de réessayer, soit en secondes (Retry-After: 120), soit sous forme de date HTTP.
HTTP/1.1 429 Too Many Requests
Content-Type: text/html
Retry-After: 3600Ne le confondez pas avec ses voisins : une erreur 503 signale un service indisponible ou saturé, une erreur 403 un accès interdit, une erreur 500 un bug côté serveur. Le 429, lui, dit : « vous, précisément, allez trop vite ».
Quel paramètre serveur déclenche une erreur 429 ?#
Un serveur ne renvoie jamais un 429 par accident. Il faut qu'une règle de limitation ait été écrite quelque part. Selon l'endroit, ce n'est pas le même réglage, ni le même correctif. Voici les quatre origines les plus courantes.
1. nginx : limit_req_zone, limit_req et burst#
Sur nginx, la limitation repose sur le module ngx_http_limit_req_module, avec deux directives qui travaillent ensemble.
http {
limit_req_zone $binary_remote_addr zone=search:10m rate=1r/s;
server {
location /search/ {
limit_req zone=search burst=5 nodelay;
limit_req_status 429;
}
}
}Ligne par ligne :
$binary_remote_addrest la clé de comptage : ici, une requête est attribuée à l'adresse IP de celui qui l'envoie. Toutes les requêtes de la même IP partagent le même compteur.zone=search:10mnomme la zone mémoire qui stocke ces compteurs (10 Mo).rate=1r/sfixe le débit autorisé : une requête par seconde en moyenne. Pour moins d'une requête par seconde, on l'exprime par minute :30r/méquivaut à une demi-requête par seconde.burst=5autorise jusqu'à 5 requêtes excédentaires en rafale. Sansnodelay, ces requêtes sont retardées pour respecter le débit ; avecnodelay, elles sont servies immédiatement, mais elles consomment le burst.- Au-delà du burst, la requête est rejetée. Le code renvoyé est celui de
limit_req_status, dont la valeur par défaut est 503, pas 429.
C'est un point qui déroute beaucoup d'administrateurs : si vous voyez un 429 sur un site servi par nginx, c'est que quelqu'un a écrit limit_req_status 429;, ou que la limitation vient d'une autre couche (CDN, application). Et si vous voyez un 503 alors que vous cherchiez un 429, c'est peut-être bien la même règle avec son statut par défaut.
Chaque refus est consigné dans le journal d'erreurs (limit_req_log_level, niveau error par défaut) avec une ligne du type limiting requests, excess: 5.320 by zone "search". C'est l'endroit à consulter en premier pour savoir quelle zone a déclenché le blocage.
2. Cloudflare : une règle de limitation de débit (et l'erreur 1015)#
Si votre site passe par Cloudflare, la limitation peut être appliquée avant même que la requête n'atteigne votre serveur. Une règle de limitation de débit Cloudflare se définit par :
- une caractéristique de comptage (l'IP, l'IP avec prise en charge du NAT, un en-tête, un cookie, le chemin, le pays…) ;
- un nombre de requêtes (
requests_per_period) sur une période (10 secondes, 1, 2, 5 ou 10 minutes, ou 1 heure via l'API) ; - une action (bloquer, défi de sécurité, journaliser) ;
- une durée de mitigation (
mitigation_timeout) : le temps pendant lequel l'action continue de s'appliquer une fois le seuil dépassé.
Quand un visiteur dépasse le seuil, il voit typiquement la page erreur 1015 (« vous faites l'objet d'une limitation de débit ») ou une réponse 429 personnalisée. La documentation Cloudflare recommande aux visiteurs d'attendre avant de réessayer, et aux propriétaires d'ajuster les seuils ou la durée de blocage.
3. L'application elle-même : le « rate limiter »#
De nombreux frameworks intègrent leur propre limiteur. Avec Symfony, par exemple, un limiteur se déclare avec une politique, une limite et un intervalle :
framework:
rate_limiter:
anonymous_api:
policy: 'fixed_window'
limit: 100
interval: '60 minutes'Le contrôleur crée ensuite un limiteur avec une clé (l'IP du client dans l'exemple de la documentation) et consomme un jeton à chaque appel. Quand la limite est atteinte, ensureAccepted() lève une exception que Symfony transforme en réponse 429 avec un en-tête Retry-After. Les trois politiques disponibles se comportent différemment : fixed_window (une fenêtre fixe, avec un risque de rafales à la jonction de deux fenêtres), sliding_window (fenêtre glissante, qui lisse ces rafales) et token_bucket (un budget qui se reconstitue en continu).
C'est aussi ce qui se passe côté WordPress ou PrestaShop lorsqu'un module de sécurité limite les tentatives de connexion ou les appels à certaines URL : le réglage (« 5 tentatives par 15 minutes », « 60 requêtes par minute ») se trouve dans les options du module.
4. Les quotas d'une API tierce#
Quand l'erreur vient d'un service que votre code appelle (une API de paiement, de cartographie, d'IA…), le « serveur » qui limite est celui du fournisseur. À titre d'exemple, la documentation de l'API Claude mesure les limites en requêtes par minute et en jetons par minute, applique un algorithme de type « token bucket » (la capacité se reconstitue en continu plutôt qu'à heure fixe) et renvoie un 429 accompagné d'un en-tête retry-after et d'en-têtes anthropic-ratelimit-* indiquant ce qu'il reste. Elle précise aussi qu'une limite de 60 requêtes par minute peut être appliquée comme 1 requête par seconde : de courtes rafales suffisent à déclencher l'erreur.
Comment l'erreur survient : six cas concrets#
Les exemples ci-dessous sont des scénarios types (les chiffres sont là pour illustrer le mécanisme), construits à partir des réglages décrits plus haut.
Cas 1 : l'autocomplétion qui dépasse le burst#
Un site e-commerce protège sa recherche avec la configuration nginx ci-dessus (rate=1r/s, burst=5 nodelay). Le champ de recherche envoie une requête à chaque touche tapée. Un internaute qui saisit un mot de 8 lettres en moins d'une seconde déclenche 8 requêtes : la première passe, les cinq suivantes consomment le burst, les dernières sont refusées. Résultat : la liste de suggestions se fige et la console du navigateur affiche des 429, alors que le serveur est parfaitement sain.
Le réglage en cause : un burst pensé pour un humain qui clique, pas pour un script de saisie prédictive. Le correctif : temporiser côté navigateur (attendre 250 à 300 ms après la dernière frappe avant d'envoyer), et relever le burst de cette route.
Cas 2 : un bureau entier derrière une seule adresse IP#
Une entreprise de 25 personnes accède à son extranet via une seule IP publique (NAT). L'extranet limite à 30 requêtes par minute par IP. Dès que trois collègues ouvrent le même tableau de bord, le compteur commun est atteint, et tout le monde reçoit un 429, y compris la personne qui vient de se connecter. Le même phénomène touche les VPN d'entreprise et les réseaux mobiles, où des milliers d'abonnés partagent parfois une même adresse.
Le réglage en cause : une clé de comptage basée uniquement sur l'IP. Le correctif : compter par compte utilisateur ou par cookie de session pour les zones authentifiées, ou relever le seuil pour les IP connues.
Cas 3 : le proxy ou le CDN qui masque l'IP des visiteurs#
C'est la version la plus sournoise du cas précédent. Le site est placé derrière un reverse proxy ou un CDN. nginx, lui, ne voit que l'adresse du proxy : $binary_remote_addr vaut la même valeur pour tous les visiteurs. Un seul compteur est partagé par l'ensemble du trafic : dès que le site est un peu fréquenté, chacun reçoit un 429, sans qu'aucun visiteur ne soit fautif.
set_real_ip_from 203.0.113.0/24; # plage d'adresses de votre proxy
real_ip_header X-Forwarded-For;Le réglage en cause : la clé de comptage lit l'IP du proxy. Le correctif : restaurer l'IP réelle du visiteur avec le module ngx_http_realip_module (directives set_real_ip_from et real_ip_header), en ne faisant confiance qu'aux adresses de votre proxy.
Cas 4 : une attaque sur wp-login.php#
Un site WordPress reçoit des centaines de tentatives de connexion par minute venant d'un réseau de robots. Une règle Cloudflare du type « plus de 5 requêtes en 10 secondes sur /wp-login.php depuis la même IP : bloquer pendant 10 minutes » entre en action. Les robots reçoivent leur 429 ou leur page 1015, ce qui est le but recherché. Mais l'administrateur légitime qui se trompe trois fois de mot de passe et rafraîchit la page peut, lui aussi, se retrouver bloqué pendant toute la durée de mitigation.
Le réglage en cause : la durée de mitigation, et l'absence d'exception pour vos propres adresses. Le correctif : une exception pour l'IP du bureau, ou un défi de sécurité plutôt qu'un blocage sec.
Cas 5 : un script qui appelle une API en boucle#
Un développeur lance un script qui enrichit 500 fiches produit avec une API tierce limitée à 60 requêtes par minute. Le script envoie ses requêtes en boucle, sans pause. Comme le fournisseur applique cette limite à raison d'environ une requête par seconde, les premières passent, puis les 429 s'enchaînent. Pire : si le script réessaie immédiatement, il continue de consommer le quota et prolonge lui-même le blocage.
Le réglage en cause : le quota de l'API (requêtes par minute) et un client qui ignore Retry-After. Le correctif : respecter l'en-tête, espacer les appels et réessayer avec un délai croissant (voir plus bas).
Cas 6 : Googlebot qui reçoit des 429#
Le 429 n'est pas toujours une erreur à supprimer : c'est aussi un outil. Google indique que renvoyer un 500, un 503 ou un 429 à son robot d'exploration réduit sa fréquence de passage quand un grand nombre d'URL renvoient ces codes, et le recommande pour une courte période (quelques heures, un à deux jours). Au-delà, cela peut nuire à l'affichage du site dans les produits Google, et une URL qui renvoie ces codes pendant plusieurs jours peut être retirée de l'index. Une règle de limitation trop stricte, qui frappe les robots d'indexation, peut donc coûter du référencement sans que personne ne s'en aperçoive.
Le réglage en cause : une limite qui s'applique aussi aux robots d'indexation légitimes. Le correctif : vérifier les journaux pour repérer les 429 servis à Googlebot, et l'exclure de la limitation (après vérification de son identité, pas sur la seule foi du User-Agent).
Réparer l'erreur 429, selon votre profil#
Vous êtes visiteur#
- Attendez, sans actualiser. Chaque rafraîchissement est une requête de plus qui peut prolonger le blocage. Si la page affiche un délai ou si vous pouvez lire l'en-tête
Retry-After, respectez-le. - Fermez les onglets ouverts sur le même site. Un onglet qui se recharge automatiquement peut consommer votre quota en arrière-plan.
- Changez de réseau (4G plutôt que le Wi-Fi partagé, ou désactivez un VPN très utilisé) : si la limite était liée à une IP partagée, elle disparaît.
- Vérifiez vos extensions de navigateur (gestionnaires de téléchargement, outils de SEO, bloqueurs qui rechargent des ressources) qui multiplient les requêtes.
- Si l'erreur persiste, contactez le propriétaire du site en lui indiquant l'heure et votre adresse IP.
Vous êtes propriétaire du site#
Ne désactivez pas la limitation au premier 429 signalé : elle vous protège des robots et des abus. Procédez dans l'ordre.
- Identifiez qui émet le 429. Depuis un terminal :
curl -I https://votresite.fr/la-page-concernee. Regardez l'en-têteServeret la présence d'en-têtes propres à un CDN, ainsi queRetry-After. Une page 1015 pointe vers Cloudflare ; sinon, c'est votre serveur web ou votre application. - Lisez les journaux. Sur nginx, cherchez
limiting requestsdans le journal d'erreurs : la ligne donne le nom de la zone et l'IP concernée. Dans Cloudflare, le journal des événements de sécurité indique la règle déclenchée. - Déterminez la cause réelle avec le tableau ci-dessous.
- Corrigez le réglage, pas le symptôme : ajustez le débit ou le burst de la seule route concernée, corrigez la clé de comptage, restaurez l'IP réelle, ajoutez des exceptions ciblées.
- Testez, puis rechargez proprement. Avec nginx, vérifiez la syntaxe (
nginx -t) avant tout rechargement.
| Symptôme observé | Cause probable | Remède |
|---|---|---|
| Tout le site renvoie 429 pour tout le monde | La clé de comptage lit l'IP du proxy ou du CDN | Restaurer l'IP réelle (realip), vérifier la configuration du proxy |
| Un bureau ou un VPN est bloqué, le reste du monde non | IP partagée (NAT) et seuil trop bas | Compter par compte ou par cookie, relever le seuil, ajouter une exception |
| Une fonction précise plante (recherche, panier, API interne) | Burst trop bas pour cette route | Relever le burst de la route, temporiser côté navigateur |
| Blocages sur la page de connexion | Règle anti-force brute trop stricte ou mitigation trop longue | Exception pour vos IP, défi de sécurité, durée raccourcie |
| Chute d'exploration dans la Search Console | Les robots d'indexation sont limités | Exclure les robots vérifiés de la limitation |
| Un script ou un module dépasse son quota | Boucle sans temporisation, appels redondants | Mettre en cache, regrouper les appels, réessayer avec délai croissant |
Pour un site vitrine, la bonne limite n'est pas la plus basse possible, mais celle qui bloque un robot sans jamais gêner un visiteur qui navigue normalement. Comme l'écrit la RFC 6585, un serveur n'est d'ailleurs pas obligé de répondre par un 429 : il peut aussi couper la connexion ou prendre d'autres mesures.
Vous êtes développeur et votre code reçoit des 429#
Le principe est simple : ne jamais réessayer immédiatement. Lisez Retry-After quand il existe (en secondes ou sous forme de date), sinon appliquez un délai qui double à chaque tentative, avec un petit aléa pour éviter que tous vos clients ne repartent au même instant.
function callWithBackoff(callable $request, int $maxAttempts = 5)
{
for ($attempt = 1; ; $attempt++) {
$response = $request();
if (429 !== $response->getStatusCode() || $attempt >= $maxAttempts) {
return $response;
}
$header = $response->getHeaderLine('Retry-After');
if ('' !== $header && ctype_digit($header)) {
$delay = (int) $header; // secondes
} elseif ('' !== $header && false !== ($ts = strtotime($header))) {
$delay = max(0, $ts - time()); // date HTTP
} else {
$delay = min(30, 2 ** $attempt) + random_int(0, 1000) / 1000;
}
usleep((int) ($delay * 1_000_000));
}
}Trois bonnes pratiques complètent ce mécanisme : limiter la concurrence (quelques requêtes en parallèle plutôt que des centaines), mettre en cache les réponses qui ne changent pas, et répartir les gros traitements dans le temps avec une file d'attente. Attention enfin aux 429 qui ne sont pas des limites de débit : chez certains fournisseurs d'API, l'atteinte d'un plafond de dépense mensuel renvoie elle aussi un 429, sans en-tête retry-after. Réessayer ne servira alors à rien tant que le plafond n'est pas relevé ou réinitialisé.
Prévenir le retour de l'erreur#
- Documentez chaque limite : où elle se trouve, quelle clé elle utilise, quel seuil, pourquoi.
- Renvoyez un vrai
Retry-After: c'est ce qui permet aux clients bien écrits de se réguler tout seuls. - Surveillez le nombre de 429 dans vos journaux ou votre outil de supervision : une hausse soudaine signale un robot, une régression front ou une limite mal calibrée.
- Distinguez vos publics : visiteurs anonymes, utilisateurs connectés, robots vérifiés et API n'ont pas les mêmes besoins.
- Testez la limite après chaque modification de l'infrastructure (nouveau proxy, nouveau CDN, migration d'hébergement).
Si l'origine du 429 reste introuvable sur votre site, ou si une limitation mal réglée bloque vos clients, notre équipe peut auditer la configuration de votre serveur et de votre CDN : contactez-nous.
Questions fréquentes#
Une erreur 429 est-elle un problème chez moi ou chez le site ?#
Dans la grande majorité des cas, elle vient du site : c'est lui qui applique la limite. Mais c'est votre comportement (ou celui de votre réseau, de votre extension, de votre script) qui la déclenche. Attendre, arrêter de rafraîchir et changer de réseau règlent presque toujours le problème côté visiteur.
Combien de temps dure un blocage 429 ?#
Cela dépend entièrement du réglage du site. L'en-tête Retry-After, quand il est présent, donne le délai exact. Avec Cloudflare, la durée de blocage est définie par le propriétaire du site dans sa règle (durée de mitigation) ; avec une API à jetons, la capacité se reconstitue en continu.
Pourquoi nginx renvoie-t-il un 503 au lieu d'un 429 ?#
Parce que limit_req_status vaut 503 par défaut. Pour obtenir un 429 sur les requêtes refusées, il faut ajouter la directive limit_req_status 429; dans le bloc concerné.
Un VPN peut-il provoquer une erreur 429 ?#
Oui. Un VPN fait partager une même adresse IP à de nombreux utilisateurs ; si le site compte les requêtes par IP, le compteur est atteint plus vite. Changer de serveur VPN ou le désactiver temporairement est un test simple.
Une erreur 429 peut-elle nuire à mon référencement ?#
Oui, si elle est servie de façon prolongée aux robots d'exploration. Google précise que ces codes ralentissent l'exploration et qu'une URL qui les renvoie plusieurs jours de suite peut être retirée de l'index. Vérifiez que vos règles de limitation n'affectent pas les robots légitimes.
Article rédigé le 28/09/2026 par l'équipe Websource à partir des sources citées ci-dessus, puis relu avant publication. Une information vous semble inexacte ou datée ? Signalez-le nous, nous corrigeons.







