Un site e-commerce de 22 000 pages perd 38 % de son trafic organique en trois semaines. La cause : un déploiement a remplacé les 301 historiques par des 302, et le serveur renvoie un 200 sur les pages supprimées au lieu d'un 410. Googlebot continue de crawler des milliers de pages mortes pendant que les nouvelles URLs ne récupèrent jamais l'autorité des anciennes. Tout ça se résume à quelques chiffres dans un en-tête HTTP.
Les status codes ne sont pas un détail d'infrastructure. Ce sont les signaux primaires que Googlebot interprète pour décider quoi crawler, quoi indexer, et quoi oublier. Ce guide couvre chaque famille de codes avec son impact SEO réel, des configurations serveur exploitables, et les pièges que même des équipes expérimentées rencontrent en production.
Les 2xx : quand tout va bien (ou pas)
200 OK — Le seul code qui indexe
Un 200 indique à Googlebot que la ressource existe et que le contenu renvoyé est la réponse définitive. C'est le seul status code qui déclenche l'indexation du contenu. Tout le reste est un signal de redirection, d'erreur, ou d'attente.
Le piège classique : les soft 404. Votre framework renvoie un 200 avec un template "Page non trouvée" parce que le routing côté serveur ne lève pas d'exception. Google Search Console les signale comme "Soft 404" dans le rapport de couverture, mais le dommage est déjà fait : le crawl budget est gaspillé sur des pages vides qui diluent la qualité globale du site.
Pour un site Next.js, la différence entre un soft 404 et un vrai 404 tient à quelques lignes dans getServerSideProps :
// pages/product/[slug].tsx — Next.js
export const getServerSideProps: GetServerSideProps = async (context) => {
const { slug } = context.params as { slug: string };
const product = await getProductBySlug(slug);
if (!product) {
return {
notFound: true, // Renvoie un vrai 404, pas un 200 avec un message d'erreur
};
}
// Produit discontinué → 410 Gone
if (product.status === 'discontinued' && !product.replacement) {
return {
redirect: {
destination: '/404',
statusCode: 410,
permanent: true,
},
};
}
// Produit remplacé → 301 vers le successeur
if (product.status === 'discontinued' && product.replacement) {
return {
redirect: {
destination: `/product/${product.replacement.slug}`,
statusCode: 301,
permanent: true,
},
};
}
return { props: { product } };
};
Ce pattern couvre les trois cas réels d'un catalogue produit : page active (200), produit supprimé sans remplacement (410), produit remplacé (301). La différence entre une soft 404 et une vraie 404 a un impact direct sur la vitesse à laquelle Google déindexe les pages mortes.
204 No Content — Le cas des endpoints AJAX
Le 204 signifie "requête traitée, pas de corps de réponse". Aucun impact SEO direct — Googlebot ne tente pas d'indexer une réponse sans corps. Mais si vos pages SPA dépendent d'un endpoint API qui renvoie 204 au lieu du contenu attendu, le renderer de Google verra une page vide. Le status code de la page HTML sera 200, mais le contenu sera absent.
206 Partial Content — Range requests et ressources lourdes
Le 206 apparaît sur les requêtes avec header Range, typiquement pour les vidéos ou les PDF volumineux. Googlebot utilise les range requests pour les fichiers lourds. Si votre serveur ne supporte pas correctement les range requests sur les fichiers PDF que vous voulez indexer, Googlebot peut abandonner le téléchargement et ne jamais indexer le contenu du document.
Les 3xx : redirections et transfert d'autorité
301 vs 302 — Le transfert de PageRank n'est plus le vrai problème
Depuis 2016, Google a confirmé que les 301 et 302 transfèrent toutes les deux le PageRank. La différence réelle n'est pas dans le transfert d'autorité — c'est dans le signal d'indexation. Un choix entre 301 et 302 détermine quelle URL Google conserve dans son index :
- 301 (Moved Permanently) : Google finit par remplacer l'URL source par l'URL cible dans l'index. Le signal est clair : l'ancienne URL est morte.
- 302 (Found) / 307 (Temporary Redirect) : Google garde l'URL source dans l'index, en supposant que la redirection est temporaire. Si elle reste en place des mois, Google finit par la traiter comme une 301 — mais avec un délai qui peut atteindre plusieurs semaines.
Le vrai danger des 302 mal utilisées : sur une migration de site de old-domain.com vers new-domain.com, des 302 au lieu de 301 signifient que Google conserve les anciennes URLs dans l'index pendant des semaines, voire des mois. Pendant ce temps, les utilisateurs qui cliquent dans les SERPs atterrissent sur l'ancien domaine et sont redirigés — ajoutant de la latence et un signal de qualité dégradé.
Les chaînes de redirections — Le coût cumulé
Googlebot suit jusqu'à 10 redirections en chaîne, mais chaque hop supplémentaire consomme du crawl budget et ajoute de la latence. Plus critique : dans la pratique, les chaînes de redirections s'accumulent au fil des migrations et des refontes. Après deux migrations, il n'est pas rare de trouver des chaînes de 4-5 hops.
Configuration Nginx pour éviter les chaînes — le principe est de toujours rediriger vers l'URL finale :
# ❌ Mauvais : chaîne de redirections accumulées
# /ancien-produit → /produit-v2 → /catalogue/produit-v2 → /shop/catalogue/produit-v2
# ✅ Correct : map direct vers l'URL finale
map $request_uri $redirect_target {
/ancien-produit /shop/catalogue/produit-v2;
/produit-v2 /shop/catalogue/produit-v2;
/catalogue/produit-v2 /shop/catalogue/produit-v2;
# Redirections post-migration trailing slash
~^(/shop/catalogue/.+)/$ $1;
}
server {
listen 443 ssl;
server_name boutique-mode.fr;
if ($redirect_target) {
return 301 $redirect_target;
}
# Gestion globale trailing slash → sans slash
location ~ ^(.+)/$ {
return 301 $1;
}
}
Ce pattern élimine les chaînes en pointant systématiquement chaque ancienne URL vers la destination finale. Le coût de maintenance augmente, mais le bénéfice sur le crawl est immédiat. La gestion du trailing slash est un cas particulier qui génère souvent des chaînes invisibles.
308 Permanent Redirect — Le 301 qui préserve la méthode HTTP
Le 308 est l'équivalent strict du 301 : permanent, mais il force le client à conserver la méthode HTTP originale (POST reste POST). En SEO, son usage est marginal — Googlebot crawle en GET. Mais si vous avez des formulaires dont les URLs d'action changent et que vous voulez que les soumissions POST suivent la redirection sans être transformées en GET, le 308 est le bon choix côté UX. Côté SEO, Google le traite comme un 301.
Les 4xx : erreurs client et signaux de déindexation
404 Not Found — Le signal de suppression standard
Un 404 indique à Google que la page n'existe pas. Googlebot va progressivement la retirer de l'index — mais "progressivement" peut signifier des semaines. Google recrawle les URLs 404 périodiquement pour vérifier si elles reviennent. Ce recrawl consomme du budget, surtout si vous avez des milliers de pages supprimées.
410 Gone — Le 404 qui accélère la déindexation
Le 410 est un signal plus fort que le 404 : "cette ressource a existé et a été définitivement supprimée". Google traite le 410 différemment en recrawlant l'URL moins fréquemment après la première découverte. Selon la documentation Google sur la suppression de contenu, le 410 est le signal recommandé pour les pages définitivement retirées.
Scénario concret : un média en ligne avec 45 000 articles supprime 8 000 anciens articles pour lutter contre l'index bloat. Avec des 404, Googlebot recrawle ces 8 000 URLs régulièrement pendant 2-3 mois avant de réduire la fréquence. Avec des 410, la déindexation s'accélère et le crawl budget récupéré est redistribué vers les articles actifs. Sur ce volume, le gain observé est typiquement une augmentation de 15-25 % du taux de crawl des pages utiles dans les 4-6 semaines qui suivent.
403 Forbidden — L'erreur mal comprise
Le 403 signifie "accès refusé". Google le traite comme un 404 en termes de déindexation, mais avec une nuance : si Googlebot reçoit un 403, il peut considérer que la page existe mais qu'il n'y a pas accès. Le résultat dans Search Console apparaît dans les erreurs de crawl, et Google peut choisir de ne pas indexer la page tout en continuant à la crawler régulièrement pour vérifier si l'accès est rétabli.
Le cas typique : un site qui protège ses pages par authentification mais oublie de servir un robots.txt approprié ou des directives noindex. Résultat : des centaines d'erreurs 403 dans Search Console, du crawl budget gaspillé, et aucune page utile à la place. Si la page ne doit jamais être indexée, bloquez-la dans le robots.txt pour éviter que Googlebot ne tente même d'y accéder.
429 Too Many Requests — Le rate limiting qui bloque le crawl
Le 429 est le code que votre serveur ou WAF renvoie quand un client dépasse la limite de requêtes. Le problème : certains CDN et reverse proxies envoient des 429 à Googlebot quand le crawl s'intensifie. Googlebot respecte le 429 et ralentit — ce qui peut diviser votre taux de crawl par 10.
Vérification rapide avec curl pour simuler ce que voit Googlebot :
# Tester si votre serveur rate-limite les crawlers
for i in $(seq 1 50); do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-H "User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
"https://boutique-mode.fr/catalogue/page/$i")
echo "Page $i: $STATUS"
# Pas de sleep — on simule un crawl rapide
done
# Si vous voyez des 429 apparaître après 20-30 requêtes,
# votre rate limiter bloque Googlebot.
# Vérifier les headers de réponse pour le Retry-After
curl -I -H "User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
"https://boutique-mode.fr/catalogue/page/1" 2>/dev/null | grep -i "retry-after"
La solution : whitelistez les IPs de Googlebot dans votre WAF. Google publie ses plages d'IP via un fichier JSON. Si vous utilisez Cloudflare comme CDN, une règle WAF sur le header CF-Connecting-IP matchant ces plages suffit.
Le 503 Service Unavailable — L'outil de maintenance sous-estimé
Le 503 est le code le plus puissant et le plus mal utilisé en SEO technique. Son rôle : indiquer à Googlebot que le contenu est temporairement indisponible et qu'il doit revenir plus tard. Couplé au header Retry-After, c'est le mécanisme officiel pour les maintenances planifiées.
Pourquoi le 503 préserve votre indexation
Quand Googlebot reçoit un 503, il ne déindexe pas la page. Il la remet dans sa file de crawl pour une visite ultérieure. C'est fondamentalement différent d'un 404 ou d'un 500 : avec un 503 + Retry-After, vous dites "revenez dans X secondes/minutes/heures, tout ira bien".
Un 500 (Internal Server Error) répété, en revanche, finit par provoquer une déindexation. Google interprète les erreurs 500 persistantes comme un signe que la page est cassée de façon durable.
Configuration pour une fenêtre de maintenance
# maintenance.conf — à inclure dans votre config Nginx pendant la maintenance
# Activé via: ln -s /etc/nginx/maintenance.conf /etc/nginx/conf.d/maintenance.conf && nginx -s reload
# Whitelister les IPs internes pour tester en prod
geo $maintenance_bypass {
default 0;
192.168.1.0/24 1; # Réseau interne
10.0.0.0/8 1; # VPN équipe
}
server {
listen 443 ssl;
server_name boutique-mode.fr;
# Bypass pour l'équipe
if ($maintenance_bypass) {
set $maintenance off;
}
# Laisser passer les assets statiques (évite de casser le template de maintenance)
location ~* \.(css|js|png|jpg|svg|woff2)$ {
try_files $uri =404;
}
# Laisser passer le robots.txt (ne JAMAIS renvoyer un 503 sur robots.txt)
location = /robots.txt {
try_files $uri =404;
}
# Tout le reste → 503 avec Retry-After
location / {
if ($maintenance != off) {
add_header Retry-After 3600 always; # Revenez dans 1h
return 503;
}
# Config normale ici
proxy_pass http://backend;
}
# Page d'erreur 503 personnalisée
error_page 503 @maintenance;
location @maintenance {
add_header Retry-After 3600 always;
add_header Content-Type "text/html; charset=utf-8" always;
root /var/www/maintenance;
try_files /index.html =503;
}
}
Points critiques dans cette configuration :
Retry-Afterest obligatoire : sans ce header, Googlebot ne sait pas quand revenir. Il réessaiera selon son propre planning, qui peut être beaucoup plus tard.- Ne renvoyez jamais un 503 sur
robots.txt: si Googlebot ne peut pas accéder au robots.txt, il peut suspendre temporairement tout le crawl du site par précaution. - Durée maximale réaliste : Google tolère quelques heures de 503. Au-delà de 24-48h, le risque de déindexation progressive augmente. Si votre maintenance dure plus longtemps, vous avez un problème d'architecture, pas de SEO.
Le piège du 503 accidentel
Certains frameworks applicatifs renvoient un 503 quand la base de données est surchargée ou quand un service backend est down. Si cela arrive sur vos pages les plus crawlées (homepage, pages catégories), Googlebot peut réduire drastiquement le crawl rate de tout le site pendant plusieurs jours. Un outil de monitoring comme Seogard détecte ces 503 intermittents en temps réel — le genre de problème qui passe inaperçu dans les logs serveur mais qui apparaît clairement dans les rapports de crawl.
Les 5xx : erreurs serveur et dégradation progressive
500 Internal Server Error — L'urgence silencieuse
Le 500 est le code par défaut quand votre application plante. Il n'a pas de sémantique précise — c'est un catch-all pour "quelque chose a cassé côté serveur". L'impact SEO dépend de la fréquence et de la durée :
- 500 intermittent (quelques requêtes par jour) : Googlebot réessaie et finit par obtenir un 200. Impact minimal si le ratio reste faible.
- 500 persistant sur des URLs spécifiques : déindexation progressive de ces URLs en quelques semaines.
- 500 massif (le serveur crashe sous charge) : réduction du crawl rate global, perte de positions sur l'ensemble du site.
Le diagnostic commence dans Google Search Console, rapport "Statistiques d'exploration" > "Réponses d'exploration". Vous y verrez le ratio de réponses 5xx par jour. Screaming Frog en mode liste (en important les URLs depuis votre sitemap) permet de scanner massivement vos pages pour identifier celles qui renvoient un 500.
502 Bad Gateway et 504 Gateway Timeout — Les problèmes d'infrastructure
Le 502 signifie que votre reverse proxy (Nginx, Cloudflare, un load balancer) n'a pas pu obtenir une réponse valide du backend. Le 504 signifie que le backend n'a pas répondu dans le délai imparti.
Pour le SEO, l'impact est identique au 500 : Googlebot reçoit une erreur et replanifie le crawl. La différence est dans le diagnostic :
- 502 : vérifiez que votre process backend (Node, PHP-FPM, Gunicorn) est bien en train de tourner et que le socket/port est accessible.
- 504 : vos pages mettent trop longtemps à se générer. C'est fréquent sur les pages SSR complexes avec de multiples appels API. La solution est soit le caching, soit l'optimisation des requêtes, soit l'augmentation du timeout — mais cette dernière option ne fait que masquer le problème.
Un 504 qui se produit spécifiquement sur les pages de pagination profondes (page 50, page 100) est un signal que vos requêtes SQL ne sont pas paginées efficacement (offset-based au lieu de cursor-based). Googlebot crawle ces pages paginées profondes, et si elles timeout systématiquement, c'est une portion entière de votre catalogue qui disparaît de l'index.
Audit et monitoring : détecter les anomalies avant Google
L'audit initial avec Screaming Frog et la Search Console
Un audit de status codes se fait en deux passes complémentaires :
Passe 1 — Crawl interne : Screaming Frog crawle votre site en suivant les liens internes. Configurez-le pour utiliser le user-agent de Googlebot et vérifiez les codes de réponse de chaque URL. Exportez les 3xx, 4xx et 5xx dans des onglets séparés. Cherchez les patterns :
- Des 302 qui devraient être des 301 (redirection en place depuis plus de 3 mois)
- Des 200 sur des pages qui devraient retourner 404/410 (soft 404)
- Des chaînes de redirections (colonne "Redirect Chain" dans l'export)
Passe 2 — Données Google : dans Search Console, le rapport "Pages" liste les URLs avec leur statut d'indexation et la raison de l'exclusion. Croisez les URLs "Exclue : Erreur serveur (5xx)" avec vos logs serveur pour identifier les plages horaires et les patterns d'URL affectés. L'URL Inspection API permet d'automatiser cette vérification sur des lots d'URLs.
Le monitoring continu — Ce que l'audit ponctuel ne capte pas
L'audit ponctuel capture un instantané. Il ne détecte pas les régressions post-déploiement : un merge qui casse le routing, une migration de base de données qui rend des pages inaccessibles, une mise à jour CDN qui modifie le comportement des redirections.
Le monitoring continu des status codes surveille vos URLs critiques à intervalles réguliers et alerte quand un 200 devient un 500, quand une 301 se transforme en 302, ou quand un 503 apparaît sur des pages qui devraient être accessibles. C'est exactement le type de régression que Seogard détecte automatiquement — un changement de status code sur une page indexée déclenche une alerte avant que l'impact SEO ne soit mesurable dans les SERPs.
Automatiser la vérification post-déploiement
Intégrez un check de status codes dans votre pipeline CI/CD. Un script simple qui vérifie vos URLs critiques après chaque déploiement évite les catastrophes :
#!/bin/bash
# check-status-codes.sh — À intégrer dans votre pipeline CI/CD
# Vérifie que les URLs critiques renvoient le bon status code après déploiement
SITE="https://boutique-mode.fr"
ERRORS=0
declare -A EXPECTED_CODES
EXPECTED_CODES["$SITE/"]="200"
EXPECTED_CODES["$SITE/catalogue/robes"]="200"
EXPECTED_CODES["$SITE/catalogue/robes?page=2"]="200"
EXPECTED_CODES["$SITE/api/health"]="200"
EXPECTED_CODES["$SITE/ancien-produit-supprime"]="410"
EXPECTED_CODES["$SITE/ancienne-categorie"]="301"
EXPECTED_CODES["$SITE/robots.txt"]="200"
EXPECTED_CODES["$SITE/sitemap.xml"]="200"
for URL in "${!EXPECTED_CODES[@]}"; do
EXPECTED="${EXPECTED_CODES[$URL]}"
ACTUAL=$(curl -s -o /dev/null -w "%{http_code}" \
-L --max-redirs 0 \
-H "User-Agent: StatusCodeChecker/1.0" \
"$URL")
if [ "$ACTUAL" != "$EXPECTED" ]; then
echo "❌ FAIL: $URL — attendu $EXPECTED, reçu $ACTUAL"
ERRORS=$((ERRORS + 1))
else
echo "✅ OK: $URL — $ACTUAL"
fi
done
if [ $ERRORS -gt 0 ]; then
echo ""
echo "🚨 $ERRORS URL(s) avec un status code inattendu. Déploiement à vérifier."
exit 1
fi
echo ""
echo "Tous les status codes sont conformes."
exit 0
Le flag --max-redirs 0 est important : il permet de vérifier que l'URL renvoie bien un 301 au lieu de suivre la redirection et de reporter le 200 final. Pour les URLs qui doivent retourner un 200, retirez ce flag ou ajustez la logique selon le cas.
Matrice de décision : quel code pour quel scénario
La théorie des status codes est simple. La difficulté est dans le mapping entre les situations business réelles et le bon code de réponse. Voici les scénarios les plus fréquents sur des sites de volume :
Page produit supprimée, remplacée par un successeur → 301 vers la page du nouveau produit. Le transfert d'autorité se fait naturellement.
Page produit supprimée, pas de remplacement, catégorie active → 301 vers la page catégorie parente. Moins précis qu'un remplacement direct, mais préserve une partie du link equity.
Page produit supprimée, catégorie entière supprimée → 410 Gone. Pas de destination pertinente pour une redirection — une 301 vers la homepage est un pattern que Google considère comme un soft 404 quand il est appliqué massivement.
Changement d'URL permanent (refonte des slugs) → 301 de l'ancienne vers la nouvelle URL. Maintenez la redirection au minimum 1 an — idéalement indéfiniment.
A/B test temporaire avec URL différente → 302 vers la variante. Google conserve l'URL originale dans l'index.
Maintenance planifiée de 2h → 503 + Retry-After: 7200 sur toutes les pages sauf robots.txt et les assets statiques.
Page derrière un paywall / authentification → Si la page ne doit pas être indexée : 403 + noindex + blocage dans robots.txt. Si la page doit être indexée (modèle freemium avec du contenu visible) : 200 avec les données structurées isAccessibleForFree.
URL avec paramètres de tracking → canonical vers l'URL sans paramètres (200 + rel=canonical), ou 301 si vous pouvez le faire côté serveur. Ne laissez jamais des variantes paramétrées en 200 sans canonical — c'est de l'index bloat garanti.
Chaque code HTTP est un contrat entre votre serveur et les moteurs de recherche. Un 200 promet du contenu indexable. Un 301 promet que le déménagement est définitif. Un 503 promet que l'absence est temporaire. Rompez ce contrat — même involontairement, même pendant quelques heures après un déploiement — et les conséquences sur l'indexation peuvent prendre des semaines à corriger. La meilleure assurance reste un monitoring continu qui vérifie ces contrats à chaque crawl, pas un audit trimestriel qui arrive toujours trop tard.