Erreur HTTP 406 Not Acceptable : causes et solutions avec WordPress, Apache et ModSecurity

Il arrive qu’un site WordPress, un CMS ou une application web refuse soudainement d’enregistrer une page, un article, une option ou un fichier, puis renvoie une erreur HTTP 406.

Le message peut ressembler à ceci :

HTTP Error 406 – Not Acceptable
An appropriate representation of the requested resource /XYZ.php could not be found on this server.

Sur WordPress, cette erreur apparaît parfois dans l’administration, notamment lors de l’enregistrement d’un article, d’un widget, d’un menu, d’un réglage de plugin ou d’une requête AJAX/REST. Dans les anciens cas, elle pouvait aussi se produire avec les éditeurs de fichiers intégrés à WordPress.

Le code HTTP 406 signifie normalement que le serveur ne peut pas produire une réponse compatible avec les en-têtes envoyés par le client, comme Accept, Accept-Encoding ou Accept-Language. MDN le décrit comme une réponse indiquant que le serveur ne peut pas fournir une représentation correspondant aux valeurs acceptables demandées par le client. Voir la documentation MDN sur HTTP 406.

En pratique, sur un site WordPress hébergé chez un prestataire, une erreur 406 vient souvent d’une règle de sécurité trop restrictive, notamment via ModSecurity, le pare-feu applicatif souvent associé à Apache, LiteSpeed ou certains environnements d’hébergement mutualisé.

Comprendre l’erreur HTTP 406 Not Acceptable

Dans la théorie HTTP, une erreur 406 Not Acceptable concerne la négociation de contenu. Le client indique les formats qu’il accepte, puis le serveur tente de fournir une représentation compatible. Si aucune variante ne convient, le serveur peut répondre 406. La documentation Apache explique ce comportement dans le cadre de la négociation de contenu. Voir la documentation Apache sur la négociation de contenu.

Dans la vraie vie d’un site WordPress, l’erreur 406 est souvent moins académique. Elle peut être déclenchée par une règle WAF qui interprète un contenu légitime comme suspect.

Exemples classiques :

  • un article contient du code HTML, JavaScript, SQL ou PHP ;
  • une option de plugin envoie une requête POST volumineuse ;
  • un constructeur de pages sauvegarde du JSON complexe ;
  • une requête REST WordPress contient des caractères jugés suspects ;
  • un formulaire contient une URL, un iframe, du code embarqué ou une chaîne ressemblant à une injection ;
  • une règle ModSecurity bloque un faux positif.

Le serveur ne vous dit pas toujours “j’ai bloqué cette requête pour cause de WAF”. Il renvoie parfois seulement une 406. Très aimable. Très peu bavard.

ModSecurity : la cause fréquente sur WordPress

ModSecurity est un pare-feu applicatif web, ou WAF. Il inspecte les requêtes HTTP afin de détecter des attaques, comme les injections SQL, le cross-site scripting, les requêtes malformées ou certains comportements suspects. Le manuel ModSecurity présente le projet comme un moteur de surveillance, journalisation et contrôle d’accès pour les applications web. Voir le manuel ModSecurity v3.

Le problème, c’est qu’une règle WAF peut confondre une action légitime avec une attaque. C’est ce qu’on appelle un faux positif.

Dans WordPress, cela peut arriver quand on publie un tutoriel technique avec des exemples de code, quand on enregistre une option contenant du HTML, ou quand un plugin sauvegarde une configuration complexe.

Résultat : l’éditeur ne peut plus éditer, l’administration ne peut plus administrer, et le serveur vous regarde avec une 406 comme si vous veniez de tenter un braquage avec un shortcode.

Première étape : identifier la requête bloquée

Avant de désactiver quoi que ce soit, commencez par identifier précisément ce qui déclenche l’erreur.

Dans le navigateur, ouvrez les outils de développement, puis l’onglet Réseau. Reproduisez l’erreur, puis regardez quelle requête renvoie 406.

Sur WordPress, cela peut être :

  • /wp-admin/post.php ;
  • /wp-admin/admin-ajax.php ;
  • /wp-json/... ;
  • /wp-admin/options.php ;
  • une URL propre à un plugin.

Ensuite, vérifiez les logs serveur. Sur Apache ou LiteSpeed avec ModSecurity, cherchez l’identifiant de la règle déclenchée. Les logs contiennent souvent un champ du type :

[id "949110"]
[msg "Inbound Anomaly Score Exceeded"]Code language: JSON / JSON with Comments (json)

C’est cet identifiant qui permet une correction propre et ciblée.

Ancienne méthode : désactiver ModSecurity dans .htaccess

Sur d’anciennes configurations Apache avec de très vieilles versions de ModSecurity, on trouvait souvent cette solution dans un fichier .htaccess placé dans le dossier concerné, par exemple /wp-admin/ :

SecFilterEngine Off
SecFilterScanPOST Off

Cette solution correspond à d’anciennes versions de ModSecurity. Elle pouvait fonctionner à l’époque, mais elle n’est plus la méthode à privilégier sur les serveurs modernes.

Avec ModSecurity 2.x et 3.x, on rencontre plutôt des directives comme SecRuleEngine, SecRuleRemoveById ou des exclusions de règles. Plusieurs références techniques rappellent que SecFilterEngine appartient aux anciennes versions et qu’avec ModSecurity 2, la directive pertinente devient SecRuleEngine. Voir cette discussion de la liste ModSecurity.

Donc, si vous mettez aujourd’hui SecFilterEngine Off dans un .htaccess, il y a de fortes chances que cela ne fasse rien, ou que le serveur renvoie une erreur de configuration.

Distingo, le livret à 2%

Solution moderne : désactiver uniquement la règle qui bloque

La meilleure correction consiste à ne pas désactiver tout ModSecurity, mais seulement la règle qui déclenche le faux positif.

Si les logs indiquent que la règle 949110 bloque une requête légitime dans WordPress, on peut demander une exclusion ciblée.

Selon l’hébergement, la correction se fait :

  • dans le panneau d’hébergement ;
  • dans la configuration Apache du vhost ;
  • dans la configuration ModSecurity ;
  • via le support de l’hébergeur ;
  • par une règle d’exclusion fournie par l’infogérant.

Sur un serveur que vous administrez, on peut exclure une règle avec SecRuleRemoveById. Exemple :

<LocationMatch "^/wp-admin/">
    SecRuleRemoveById 949110
</LocationMatch>Code language: HTML, XML (xml)

Ce n’est qu’un exemple. Il ne faut pas copier un ID au hasard : l’identifiant doit correspondre à la règle réellement déclenchée dans vos logs.

Le manuel ModSecurity documente SecRuleRemoveById comme une directive permettant de retirer une ou plusieurs règles du contexte courant. Voir le manuel ModSecurity v2.

Solution temporaire : désactiver ModSecurity sur une zone précise

Si vous ne pouvez pas identifier immédiatement la règle bloquante, vous pouvez désactiver ModSecurity sur une zone précise, mais cela doit rester temporaire et limité.

Sur un serveur Apache récent, dans une configuration de vhost ou un fichier autorisé par le serveur, on peut rencontrer une syntaxe de ce type :

<LocationMatch "^/wp-admin/">
    SecRuleEngine Off
</LocationMatch>Code language: HTML, XML (xml)

Cela désactive le moteur de règles ModSecurity pour /wp-admin/. C’est radical, donc à éviter comme solution permanente.

Si le problème concerne uniquement l’API REST, ciblez plutôt l’endpoint concerné. Par exemple :

<LocationMatch "^/wp-json/">
    SecRuleEngine Off
</LocationMatch>Code language: HTML, XML (xml)

Encore une fois, mieux vaut exclure une règle précise que désactiver le WAF sur toute une zone d’administration.

Cas d’un hébergement mutualisé

Sur un hébergement mutualisé, vous n’aurez pas toujours accès aux logs ModSecurity ni à la configuration Apache.

Dans ce cas, contactez l’hébergeur avec des informations précises :

  • l’heure exacte de l’erreur ;
  • l’URL qui renvoie 406 ;
  • l’action effectuée ;
  • l’adresse IP source ;
  • le compte ou domaine concerné ;
  • un extrait du message d’erreur ;
  • le contenu ou type de contenu qui déclenche le blocage si vous l’avez identifié.

Demandez explicitement si une règle ModSecurity ou OWASP CRS bloque la requête, puis demandez une exclusion ciblée de cette règle pour votre site.

Évitez de demander “désactivez ModSecurity partout”. Un bon support vous proposera plutôt une règle d’exclusion précise. Un très bon support vous donnera même l’ID de la règle. Oui, ça existe.

WordPress : où l’erreur 406 apparaît le plus souvent

Sur WordPress, l’erreur 406 apparaît souvent lors d’une requête POST. Cela peut concerner :

  • la sauvegarde d’un article dans Gutenberg ;
  • l’enregistrement d’un champ ACF ;
  • la sauvegarde d’options dans un plugin ;
  • un formulaire de paiement ;
  • un formulaire de contact ;
  • une requête AJAX ;
  • l’API REST ;
  • l’envoi de code dans un article technique.

Le projet Gutenberg a déjà connu des rapports d’erreur 406 liés à ModSecurity lors de la mise à jour d’articles ou pages. Dans l’un de ces rapports, un utilisateur indique que le problème venait de ModSecurity après activation/désactivation rapide du module. Voir l’issue Gutenberg liée à une erreur 406.

Certains plugins rencontrent le même type de faux positif. WP Simple Pay documente par exemple des erreurs 406/403 liées à ModSecurity lorsque certaines configurations bloquent des requêtes pourtant légitimes. Voir leur documentation.

Tester avec curl

Pour confirmer le code HTTP renvoyé par une URL, utilisez curl :

curl -I https://example.com/url-qui-pose-problemeCode language: JavaScript (javascript)

Pour inspecter les en-têtes plus précisément :

curl -v https://example.com/url-qui-pose-problemeCode language: JavaScript (javascript)

Si le problème concerne une requête POST, il faut reproduire la requête avec les données concernées. Dans ce cas, les outils de développement du navigateur ou les logs serveur restent souvent plus pratiques.

Vérifier les logs Apache, ModSecurity et PHP

Sur un serveur que vous administrez, commencez par les logs Apache :

sudo tail -f /var/log/apache2/error.logCode language: JavaScript (javascript)

Selon la configuration, ModSecurity peut aussi écrire dans un audit log dédié :

sudo tail -f /var/log/apache2/modsec_audit.logCode language: JavaScript (javascript)

Ou dans un chemin différent selon la distribution, le panneau d’hébergement ou le serveur web.

Reproduisez l’erreur pendant que les logs défilent, puis cherchez :

  • l’URL bloquée ;
  • le code HTTP 406 ;
  • un identifiant de règle [id "..."] ;
  • un message [msg "..."] ;
  • le nom du fichier ou de l’endpoint WordPress ;
  • l’adresse IP source.

C’est le meilleur moyen d’éviter les corrections au doigt mouillé.

Ne désactivez pas ModSecurity sur tout le site

La tentation est grande : une ligne, ModSecurity désactivé, plus d’erreur 406. Champagne.

Sauf que désactiver le WAF sur tout un domaine supprime une couche de protection utile contre de nombreuses requêtes malveillantes. Ce n’est pas nécessaire si une seule règle bloque un seul endpoint dans un seul contexte.

La bonne hiérarchie de correction est la suivante :

  1. identifier l’URL ou l’action bloquée ;
  2. trouver l’ID de règle dans les logs ;
  3. exclure cette règle uniquement là où elle bloque ;
  4. tester à nouveau ;
  5. documenter l’exception.

Le but n’est pas de gagner contre ModSecurity. Le but est de lui apprendre à ne pas mordre votre propre mollet.

Cas des éditeurs de fichiers WordPress

L’article original évoquait les éditeurs de fichiers intégrés à WordPress. Ces éditeurs permettaient de modifier des fichiers de thème ou d’extension depuis l’administration.

Aujourd’hui, sur un site sérieux, il vaut mieux éviter de les utiliser. Pour modifier du code WordPress, préférez un workflow propre : environnement local, dépôt Git, déploiement contrôlé, accès SFTP/SSH, ou snippets versionnés selon le contexte.

Si l’erreur 406 apparaît uniquement quand vous essayez de modifier du code depuis l’admin WordPress, le WAF fait peut-être exactement ce qu’on lui a demandé : bloquer l’envoi de code suspect via une requête web.

Dans ce cas, la meilleure solution n’est pas forcément de désactiver la règle. La meilleure solution est souvent d’arrêter d’éditer les fichiers depuis l’administration WordPress.

WordPress permet d’ailleurs de désactiver l’éditeur de fichiers avec cette constante dans wp-config.php :

define( 'DISALLOW_FILE_EDIT', true );Code language: JavaScript (javascript)

C’est plus propre, plus sûr et plus compatible avec une maintenance professionnelle.

Solution rapide si vous êtes bloqué

Si vous devez débloquer rapidement une action légitime, voici la marche à suivre :

  1. ouvrez les outils de développement du navigateur ;
  2. reproduisez l’erreur ;
  3. notez l’URL qui renvoie 406 ;
  4. regardez les logs ModSecurity ;
  5. identifiez l’ID de règle ;
  6. excluez uniquement cette règle sur cette URL ;
  7. testez à nouveau ;
  8. gardez une note de l’exception appliquée.

Sur un hébergement mutualisé, envoyez ces informations au support. Sur un serveur dédié, appliquez l’exclusion dans la configuration Apache ou ModSecurity appropriée, puis rechargez Apache :

sudo apachectl configtest
sudo systemctl reload apache2

Sur une distribution où le service s’appelle httpd, utilisez plutôt :

sudo apachectl configtest
sudo systemctl reload httpd

Résumé

Pour résoudre une erreur HTTP 406 sur WordPress ou Apache :

  • vérifiez d’abord quelle requête renvoie 406 ;
  • inspectez les logs Apache et ModSecurity ;
  • cherchez l’identifiant de règle bloquante ;
  • évitez les anciennes directives SecFilterEngine Off et SecFilterScanPOST Off ;
  • préférez SecRuleRemoveById pour exclure une règle précise ;
  • limitez l’exception à l’URL ou au dossier concerné ;
  • ne désactivez pas ModSecurity sur tout le domaine.

La correction doit être ciblée. Sinon, on transforme un faux positif gênant en vraie faiblesse serveur. Pas le meilleur échange du siècle.

Conclusion

L’erreur HTTP 406 Not Acceptable peut venir d’un problème de négociation de contenu, mais sur WordPress et les CMS hébergés derrière Apache ou LiteSpeed, elle indique souvent une règle ModSecurity trop stricte.

L’ancienne solution consistait à désactiver ModSecurity dans un .htaccess avec SecFilterEngine Off et SecFilterScanPOST Off. Cette méthode appartient aux anciennes versions de ModSecurity et ne constitue plus une bonne pratique.

La bonne approche moderne consiste à identifier la requête bloquée, trouver la règle responsable dans les logs, puis créer une exclusion ciblée avec SecRuleRemoveById ou via le support de l’hébergeur.

En clair : on ne coupe pas l’alarme de toute la maison parce qu’un détecteur confond le grille-pain avec un incendie. On règle le détecteur.

Sources utiles

Gravatar for Matt Biscay

Je suis Matt Biscay, développeur WordPress & WooCommerce certifié chez Codeable, administrateur système et enseignant.

J’aide les entreprises à créer, optimiser et fiabiliser leurs sites WordPress avec une approche technique propre : performance, sécurité, maintenance, développement sur mesure et résolution de problèmes complexes.

Sur Skyminds, je partage des tutoriels WordPress, WooCommerce, Linux et administration système, avec des solutions testées sur des cas réels et pensées pour durer.

Découvrez mes services WordPress et WooCommerce.

9 pensées sur “Erreur HTTP 406 Not Acceptable : causes et solutions avec WordPress, Apache et ModSecurity”

  1. MERCI pour cet article providentiel! J’ai cherché trop longtemps à trouver pourquoi la fonction flash upload() ne fonctionnait pas. En fait c’était pas elle qui ne fonctionnait pas mais bien des problèmes de sécurité sur le serveur…

    Reply
  2. bonjour

    j ai acces a mon site moto favoris mais des que je desire poster un com( donc je m enregistre avec mon identifiant et mot de passe) ce message apparait ensuite
    je ne peux donc rien faire

    tres desagreable car je n ai trouve aucune solution

    Reply
  3. Salut THIERRY,

    Je te conseille de contacter l’administrateur du site de moto : étant donné que cela touche la configuration du serveur, lui seul peut débloquer la situation.

    Reply
  4. salut, j’ai fais scrupuleusement ce que tu dis… j’ai une erreur 500 (dans FF et IE) qui m’est retournée. De plus, moi l’erreur 406 je l’ai aussi au chargement la page d’accueil (que sous FF dans IE c’est ok)

    Peux tu m’aider, Merci.

    Reply
    • Salut grib,

      Quels changements as-tu effectué sur ton site avant l’apparition de l’erreur 500 ? Regarde tes fichiers logs si tu y as accès.

      Par contre que tu obtiennes l’erreur dans un navigateur et pas dans l’autre, ce n’est pas normal : supprime le cache et les cookies du navigateur.

      Reply
  5. Salut a tous,

    j’ai un gros problème et je veux de l’aide s’il vous plait !
    Mon site marche très bien ,mais parfois il m’affiche l’erreur 406 not acceptable soudainement dans toutes les sections du site (pages,administration ),la seule solution que j’ai pour que mon site fonction bien c’est de vider l’historique(les cookies pour plus préciser)
    j’ai testé dans le navigateur texte Lynx j’étais surpris qu’il me met l’erreur en permanence .
    Je vous demande si quelqu’un a une solution pour moi s’il vous plait .

    Reply

Opinions