Lors de l'appel d'une API, 401 Unauthorized, 403 Forbidden et 429 Too Many Requests sont les trois types d'erreurs les plus courants.
Elles appartiennent toutes aux erreurs client 4xx, mais leurs méthodes de résolution sont complètement différentes :
- 401 : échec d'authentification——le serveur ne peut pas confirmer « qui vous êtes »
- 403 : accès refusé——le serveur comprend la requête, mais n'autorise pas son exécution
- 429 : trop de requêtes——la vitesse d'appel ou l'utilisation dépasse les limites
Si vous ne distinguez pas les types d'erreurs et réessayez directement, cela ne résoudra pas seulement le problème, mais pourra également provoquer une tempête de tentatives, voire entraîner des restrictions supplémentaires sur l'interface.
Cet article expliquera, à l'aide d'une liste de vérification de dépannage, de commandes curl et de code Node.js, comment traiter ces trois types d'erreurs.
¶ Comprendre 401, 403 et 429 en un tableau
| Code d'état | Signification principale | Causes courantes | Faut-il réessayer immédiatement ? |
|---|---|---|---|
401 Unauthorized |
Absence d'identifiants d'authentification valides | API Key incorrecte, Token expiré, format d'en-tête d'authentification incorrect | Il ne faut pas réessayer tel quel |
403 Forbidden |
Le serveur refuse de traiter la requête | Permissions insuffisantes, restrictions d'IP ou géographiques, stratégie de ressource, blocage WAF | Généralement non |
429 Too Many Requests |
Les requêtes dépassent les limites de débit ou de quota | Concurrence trop élevée, dépassement de QPS, quota épuisé | Réessayer après avoir attendu |
Il convient de noter que, bien que le nom anglais de 401 soit Unauthorized, dans le dépannage réel, il est plus approprié de le comprendre comme « non authentifié » ; le 403 est généralement lié à l'autorisation ou aux politiques d'accès.
¶ I. 401 Unauthorized : vérifiez d'abord les identifiants d'authentification

HTTP 401 Unauthorized indique que la requête ne possède pas les identifiants d'authentification valides requis pour la ressource cible. Une réponse 401 standard indique généralement au client le schéma d'authentification attendu par le serveur via l'en-tête de réponse WWW-Authenticate.
¶ Causes courantes
- L'en-tête de requête
Authorizationn'a pas été envoyé - L'API Key ou l'Access Token est incorrect
- Le Token a expiré ou a été révoqué
- Le schéma d'authentification est incorrect, par exemple
Bearerest absent - Les variables d'environnement ne sont pas correctement chargées
- Une clé provenant du mauvais environnement est utilisée
- Lors du transfert de la requête par un proxy ou une passerelle, l'en-tête d'authentification est perdu
- L'écart d'heure entre le client et le serveur est trop important, ce qui rend la signature invalide
¶ Erreurs courantes
L'interface requiert un Bearer Token :
Authorization: Bearer YOUR_ACCESS_TOKEN
Mais le client l'envoie sous la forme :
Authorization: YOUR_ACCESS_TOKEN
Ou l'écrit incorrectement ainsi :
Authentication: Bearer YOUR_ACCESS_TOKEN
Ces deux cas peuvent renvoyer un 401.
¶ Dépannage avec curl
Ne consultez pas uniquement le corps de la réponse au début. Ajoutez -i pour vérifier simultanément le code d'état et les en-têtes de réponse :
curl -i "https://api.example.com/v1/profile" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Accept: application/json"
Points à vérifier :
- Si
Authorizationa bien été envoyé - Si le schéma d'authentification est correct
- S'il y a des espaces ou des sauts de ligne avant ou après le Token
- Ce que renvoie
WWW-Authenticate - S'il y a des informations d'erreur telles que
invalid_token,expired_tokendans le corps de la réponse
Si vous devez consulter un processus de requête plus détaillé, vous pouvez utiliser :
curl -v "https://api.example.com/v1/profile" \
-H "Authorization: Bearer $API_TOKEN"
Remarque : les journaux de débogage peuvent contenir le Token. N'envoyez pas les journaux complets directement dans des Issues publiques, des discussions de groupe ou des tickets.
¶ Faut-il réessayer après un 401 ?
Ne réessayez pas à plusieurs reprises avec les mêmes identifiants invalides.
Processus recommandé :
- Vérifiez si la requête contient des informations d'authentification
- Vérifiez si le Token a expiré, a été révoqué ou a été copié incorrectement
- Si Refresh Token est pris en charge, actualisez une fois le jeton d'accès
- Réessayez une fois avec le nouveau Token
- Si un 401 est toujours renvoyé, arrêtez de réessayer et enregistrez l'erreur
Si vous utilisez une API Key fixe, vous devez vérifier l'état de la clé ou la remplacer par une clé valide, plutôt que de réessayer en boucle.
¶ II. 403 Forbidden : l'authentification peut avoir réussi, mais la requête est toujours refusée

403 Forbidden indique que le serveur a déjà compris la requête, mais refuse de la traiter. Pour une erreur de permission typique, même une nouvelle authentification ne résoudra pas automatiquement le problème ; si vous ne modifiez pas la requête ou la configuration des permissions, les requêtes répétées échoueront généralement toujours.
¶ Causes courantes
- Le compte ou la clé actuelle ne possède pas les permissions requises
- Le Scope du Token est insuffisant
- Vous accédez à une ressource qui n'appartient pas au projet ou au locataire actuel
- L'IP source ne figure pas dans la liste blanche
- La région d'origine de la requête est soumise à des restrictions
- Le WAF, le pare-feu ou le système anti-abus bloque la requête
- Le compte, le projet ou la ressource est désactivé
- L'interface est uniquement ouverte à certains forfaits ou rôles
- La signature est valide, mais l'étendue de ressource dans la signature ne correspond pas
- Dans un scénario de navigateur, des restrictions de politique CSRF, Origin ou Referer s'appliquent
¶ Différence entre 401 et 403
Vous pouvez les distinguer rapidement en deux phrases :
- 401 : le serveur ne peut pas confirmer qui vous êtes
- 403 : le serveur connaît ou comprend votre identité et votre requête, mais ne vous autorise pas à faire cela
Par exemple, un membre ordinaire utilise un Token valide pour appeler l'interface « supprimer une organisation » :
curl -i -X DELETE \
"https://api.example.com/v1/organizations/org_123" \
-H "Authorization: Bearer $API_TOKEN"
Si le Token est valide, mais que le compte n'est pas administrateur de l'organisation, le serveur peut renvoyer :
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"error": "insufficient_permissions",
"message": "Administrator role is required."
}
¶ Ordre de dépannage pour un 403
¶ 1. Lisez le corps de la réponse
Recherchez en priorité le code d'erreur, le rôle ou les permissions manquants, le Scope requis, l'ID de ressource refusé, ainsi que les indications liées aux politiques d'IP, de région ou de sécurité.
¶ 2. Vérifiez le Scope du Token
Par exemple, la lecture de données peut nécessiter uniquement data:read, mais la création de données peut nécessiter data:write. Un Token valide ne signifie pas que vous possédez toutes les permissions.
¶ 3. Vérifiez l'appartenance de la ressource
Confirmez que l'ID de projet, l'ID d'organisation, l'ID de locataire, l'ID utilisateur, la région ou l'environnement appartiennent au même compte ou périmètre d'autorisation que les identifiants actuels.
¶ 4. Vérifiez les politiques réseau et de sécurité
Si le code fonctionne normalement en local mais renvoie 403 après le déploiement, il faut se concentrer sur l’IP de sortie du serveur, la liste blanche d’IP, la configuration du proxy, le CDN, le WAF, la région d’origine de la requête et les en-têtes de requête associés.
¶ Ne tirez pas de conclusions uniquement à partir du code de statut
Les implémentations d’API dans la réalité ne sont pas nécessairement totalement cohérentes. Certaines plateformes peuvent renvoyer 403 lors du déclenchement d’une limitation de débit, plutôt que 429. Par exemple, l’API REST de GitHub peut renvoyer 403 ou 429 lorsque la limite de débit est dépassée, et indiquer l’état de la limitation via des en-têtes de réponse tels que x-ratelimit-remaining, x-ratelimit-reset ou retry-after.
Par conséquent, lorsque vous rencontrez 403, vous devez également vérifier de manière globale :
- Le code d’erreur métier dans le corps de la réponse
Retry-AfterX-RateLimit-RemainingX-RateLimit-Reset- La documentation officielle de la plateforme
¶ Faut-il réessayer après un 403 ?
Pour les 403 causés par des autorisations insuffisantes, des restrictions d’IP ou des politiques de ressources, réessayer à l’identique n’a aucun sens.
La bonne approche consiste à modifier les autorisations ou le Token Scope, à utiliser le bon compte ou projet, à ajuster les listes blanches et les politiques de sécurité, à corriger l’ID de ressource, et à confirmer que le service ou le forfait prend en charge cette interface. Ce n’est que lorsque la plateforme indique explicitement que ce 403 représente en réalité une limitation temporaire de débit qu’il faut attendre puis réessayer conformément aux règles de limitation.
¶ III. 429 Too Many Requests : ralentir d’abord, puis réessayer

429 Too Many Requests indique que le client a envoyé trop de requêtes sur une période donnée, c’est-à-dire qu’il a déclenché une limitation de débit. Le serveur peut indiquer au client combien de temps il doit attendre avant de réessayer via Retry-After.
¶ Causes fréquentes
- Trop de requêtes en peu de temps
- Un nombre trop élevé de tâches simultanées
- Plusieurs services partagent la même API Key
- Le code de nouvelle tentative ne possède aucun mécanisme d’attente
- Les tâches planifiées s’exécutent de manière concentrée au même moment
- Les requêtes ne sont pas mises en cache et récupèrent plusieurs fois les mêmes données
- Le quota d’un compte, d’une IP ou d’un projet unique est épuisé
- Les limites d’utilisation ou de solde du forfait
¶ Vérifiez d’abord les en-têtes de réponse
curl -i "https://api.example.com/v1/resources" \
-H "Authorization: Bearer $API_TOKEN"
Portez une attention particulière à :
Retry-After: 30
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710000000
Les noms des en-têtes de réponse peuvent différer selon les plateformes ; il convient de se référer à la documentation de la plateforme.
¶ Gérer correctement Retry-After
Les deux formats courants de Retry-After sont un nombre de secondes ou une date HTTP :
Retry-After: 30
Retry-After: Wed, 21 Oct 2026 07:28:00 GMT
Le client devrait idéalement prendre en charge ces deux formats.
¶ Pourquoi ne peut-on pas réessayer immédiatement ?
Si vous réessayez immédiatement après qu’une requête a été limitée, la nouvelle requête sera encore limitée ; plusieurs clients peuvent également réessayer simultanément, formant un « effet de troupeau ». Une méthode plus fiable consiste à :
- Respecter en priorité
Retry-After - Utiliser un recul exponentiel en l’absence de temps d’attente explicite
- Ajouter une gigue aléatoire au temps d’attente
- Définir un nombre maximal de tentatives
- Renvoyer une erreur explicite après avoir atteint la limite
¶ Node.js : gérer 429 de manière sûre
L’exemple suivant utilise le fetch intégré de Node.js, analyse en priorité Retry-After ; si le serveur ne fournit pas cet en-tête de réponse, il utilise un recul exponentiel avec une gigue aléatoire.
const sleep = (ms) =>
new Promise((resolve) => setTimeout(resolve, ms));
function parseRetryAfter(value) {
if (!value) return null;
const seconds = Number(value);
if (Number.isFinite(seconds) && seconds >= 0) {
return seconds * 1000;
}
const timestamp = Date.parse(value);
if (!Number.isNaN(timestamp)) {
return Math.max(0, timestamp - Date.now());
}
return null;
}
async function fetchWithRetry(url, options = {}, config = {}) {
const {
maxRetries = 3,
baseDelayMs = 1000,
maxDelayMs = 30_000,
} = config;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
if (attempt === maxRetries) {
throw new Error(
`请求持续受到限流,已达到最大重试次数:${maxRetries}`
);
}
const retryAfterMs = parseRetryAfter(
response.headers.get("retry-after")
);
const backoffCap = Math.min(
maxDelayMs,
baseDelayMs * 2 ** attempt
);
const jitterMs = Math.floor(Math.random() * backoffCap);
const delayMs = retryAfterMs ?? jitterMs;
console.warn(
`收到 429,第 ${attempt + 1} 次等待 ${delayMs}ms 后重试`
);
await sleep(delayMs);
}
throw new Error("请求失败");
}
Exemple d’appel :
const response = await fetchWithRetry(
"https://api.example.com/v1/resources",
{
headers: {
Authorization: `Bearer ${process.env.API_TOKEN}`,
Accept: "application/json",
},
},
{
maxRetries: 3,
baseDelayMs: 1000,
maxDelayMs: 30_000,
}
);
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`API 请求失败:${response.status} ${errorBody}`);
}
const data = await response.json();
console.log(data);
¶ Lors de la répétition de requêtes POST, il faut également considérer l’idempotence
Toutes les requêtes ne se prêtent pas à une nouvelle tentative automatique. Les requêtes de lecture telles que GET et HEAD sont généralement plus faciles à réessayer en toute sécurité. Pour les requêtes POST telles que la création de commandes, les prélèvements ou l’envoi de messages, le client peut avoir soumis la requête avec succès, mais ne pas avoir reçu de réponse en raison d’une interruption réseau. Réessayer directement dans ce cas peut entraîner des opérations en double.
Si la plateforme le prend en charge, une clé d’idempotence doit être définie pour les opérations d’écriture :
curl -i -X POST "https://api.example.com/v1/orders" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-20260331-0001" \
-d '{
"product_id": "prod_123",
"quantity": 1
}'
Le nom de l’en-tête de requête de la clé d’idempotence et sa durée de validité dépendent de la plateforme concernée ; veuillez consulter la documentation API correspondante.
¶ Liste de contrôle de dépannage en environnement de production
¶ Réception d’un 401
- La requête contient-elle un en-tête d’authentification ?
- Le schéma d’authentification tel que
Bearerest-il correct ? - Le Token a-t-il expiré, été révoqué ou mal copié ?
- La clé du bon environnement est-elle utilisée ?
- Le proxy ou la passerelle a-t-il supprimé l’en-tête d’authentification ?
- L’heure du client est-elle exacte ?
- Est-il possible d’actualiser un Token une seule fois en toute sécurité ?
¶ Réception d’un 403
- Le Token possède-t-il le Scope requis
- Le compte actuel dispose-t-il du rôle requis
- La ressource appartient-elle au projet ou au locataire actuel
- L’IP de sortie figure-t-elle dans la liste blanche
- Est-elle soumise à des restrictions de région, de WAF ou de politique de sécurité
- Le corps de la réponse indique-t-il explicitement un problème d’autorisation ou de limitation de débit
- Les en-têtes de réponse contiennent-ils des informations sur la limitation de débit
¶ Réception d’un 429
-
Retry-Aftera-t-il été lu - Les en-têtes de réponse liés à la limitation de débit ont-ils été vérifiés
- Un backoff exponentiel et une gigue aléatoire sont-ils utilisés
- Un nombre maximal de tentatives est-il défini
- La concurrence est-elle limitée
- Les résultats des requêtes répétées sont-ils mis en cache
- Les requêtes peuvent-elles être fusionnées ou envoyées par lots
- Le quota de l’offre ou la limite d’utilisation du compte est-il atteint
¶ Quelles informations de diagnostic est-il recommandé d’enregistrer ?
Il est recommandé d’enregistrer dans les journaux l’heure de la requête, le nom d’hôte et le chemin de l’API, la méthode HTTP, le code d’état, le code d’erreur métier, le request-id ou le trace-id, le Retry-After, le quota restant de limitation de débit et l’heure de réinitialisation, le nombre de tentatives et le temps d’attente réel.
Mais n’enregistrez pas la clé API complète, l’Access Token complet, le Refresh Token, le mot de passe de l’utilisateur ou les informations personnelles sensibles présentes dans le corps de la requête.
¶ La règle mnémotechnique finale
401 : corrigez d’abord les identifiants, ne réessayez pas avec un ancien Token.
403 : corrigez d’abord les autorisations ou les politiques, ne répétez pas la requête telle quelle.
429 : respectez le délai d’attente, appliquez un backoff, réduisez le débit et limitez la concurrence.
Le code d’état n’est que le point d’entrée du dépannage, pas toute la réponse. Une méthode de traitement fiable consiste à combiner le code d’état HTTP, le code d’erreur métier dans le corps de la réponse, les en-têtes de réponse associés, la documentation de la plateforme, l’ID de requête et les journaux côté serveur, afin de transformer une « erreur d’interface » en un mécanisme d’ingénierie observable, récupérable et maintenable.

