406 Not Acceptable
Utilisation
Lorsqu’une erreur 406 Not Acceptable survient, la réponse est déclenchée par un en-tête lié à la négociation, tel que Accept ou Accept-Language. Lorsque le client inclut un ou plusieurs de ces en-têtes, le serveur satisfait ces exigences dans la mesure du possible.
Les en-têtes HTTP Accept les plus courants sont :
Accept : indique le type de contenu préféré. Un serveur fournit soit du texte brut, soit une représentation HTML. Dans cet exemple, le client préfère HTML mais accepte le texte brut.
Accept: text/html, text/plain
Accept-Encoding : indique les encodages que le client accepte. Dans cet exemple, le client signale la prise en charge de la compression gzip.
Accept-Encoding: gzip
En pratique, cette erreur est rarement utilisée, car le serveur fournit plutôt une représentation par défaut. Le raisonnement part du principe que le client préfère quelque chose à rien. Lorsque la réponse 406 Not Acceptable est renvoyée, le corps du message contient la liste des représentations disponibles parmi lesquelles le client choisit.
Remarque
406 Not Acceptable signifie que le serveur ne peut pas produire de réponse correspondant aux en-têtes Accept du client (problème de format de sortie). 415 Unsupported Media Type signifie que le serveur ne comprend pas le Content-Type du corps de la requête (problème de format d’entrée). 406 concerne ce que le client souhaite recevoir, tandis que 415 concerne ce que le client a envoyé.
Impact SEO
Les moteurs de recherche comme Google n’indexent pas une URL renvoyant un statut 406 Not Acceptable. Les URL précédemment indexées qui renvoient ce code de statut sont retirées des résultats de recherche.
Exemple
Le client demande une ressource en français, mais le serveur répond 406 Not Acceptable car seules les versions allemande et anglaise sont disponibles.
Requête
GET /news HTTP/1.1
Host: example.com
Accept-Language: fr
Réponse
HTTP/1.1 406 Not Acceptable
Content-Type: text/html
Content-Length: 242
<html>
<head>
<title>French Language Not Available</title>
</head>
<body>
<p>Please choose a supported language:</p>
<p><a href="/news/news-de.html">German</a></p>
<p><a href="/news/news-en.html">English</a></p>
</body>
</html>
Comment corriger
Un 406 Not Acceptable signifie que le serveur ne dispose d’aucune représentation correspondant aux en-têtes de négociation de contenu du client.
Examinez l’en-tête Accept. Élargissez les types de médias acceptés. Par exemple, ajoutez application/json à côté de text/html, ou utilisez / pour accepter n’importe quel format. Utilisez les DevTools du navigateur (onglet Network) ou curl -v pour inspecter l’en-tête Accept exact envoyé par le client.
Vérifiez les contraintes Accept-Language. Demander une langue que le serveur ne prend pas en charge déclenche cette erreur. Élargissez la liste des langues ou ajoutez un repli avec un caractère générique (*). Les paramètres de langue du navigateur contrôlent automatiquement cet en-tête. Ajustez-les dans les préférences linguistiques du navigateur.
Supprimez les valeurs Accept-Encoding ou Accept-Charset trop restrictives. Une exigence étroite d’encodage ou de jeu de caractères limite les options du serveur. Autorisez les valeurs courantes comme gzip, deflate et UTF-8.
Inspectez le corps de la réponse à la recherche d’alternatives disponibles. Le serveur énumère souvent les représentations prises en charge dans la réponse 406. Choisissez-en une et ajustez les en-têtes de négociation en conséquence.
Vérifiez la configuration de la négociation de contenu côté serveur. Des type maps mal configurées ou des types MIME non enregistrés sur le serveur provoquent des réponses 406 inattendues. Dans Apache, mod_negotiation et MultiViews contrôlent les type maps. Vérifiez que les directives AddType enregistrent bien les types MIME requis.
Vérifiez les règles mod_security ou du WAF. Le mod_security d’Apache (et les WAF similaires) intercepte les requêtes et renvoie 406 lorsqu’une règle se déclenche sur le contenu de la requête, et non sur l’en-tête Accept. Consultez le journal d’erreurs du serveur à la recherche d’une entrée ModSecurity et relevez l’identifiant de la règle (par exemple, [id “941160”]). Mettez sur liste d’autorisation la règle concernée plutôt que de désactiver entièrement le WAF :
SecRuleRemoveById 941160
Placez cette exclusion dans la configuration du virtual host ou dans le fichier .htaccess.
Testez avec une requête minimale. Retirez tous les en-têtes de négociation et envoyez une requête nue avec curl pour déterminer si le serveur renvoie une représentation par défaut. Si la requête nue aboutit, rajoutez les en-têtes de négociation un par un pour isoler celui qui déclenche le rejet.
Vérifiez la négociation de version de l’API. Certaines API utilisent l’en-tête Accept pour le versionnement (par exemple, application/vnd.api.v2+json). L’envoi d’une chaîne de version non prise en charge produit un 406. Confirmez la valeur de version dans la documentation de l’API.
Références de code
.NET
HttpStatusCode.NotAcceptable
Rust
http::StatusCode::NOT_ACCEPTABLE
Rails
:not_acceptable
Go
http.StatusNotAcceptable
Symfony
Response::HTTP_NOT_ACCEPTABLE
Python3.5+
http.HTTPStatus.NOT_ACCEPTABLE
Java
java.net.HttpURLConnection.HTTP_NOT_ACCEPTABLE
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_NOT_ACCEPTABLE
Angular
@angular/common/http/HttpStatusCode.NotAcceptable