Geonode logo
Geonode Team

Geonode Team

Mis à jour : 7 octobre 2026

Publié : 2 septembre 2026

Qu'est-ce qu'un code d'état 415 ? Causes et solutions

Un code 415 signifie que le serveur a compris votre requête mais a rejeté le format dans lequel vous avez envoyé le corps de la requête. Cela n'a rien à voir avec des données erronées : le problème réside dans l'encapsulation. C'est pourquoi la solution consiste presque toujours à modifier un en-tête plutôt que le contenu de la requête, et c'est pourquoi ceux qui cherchent la cause du problème dans leur JSON ne trouvent rien. Ce guide présente ce que dit réellement la spécification, les quelques causes qui expliquent la quasi-totalité des cas, et comment distinguer le code 415 des trois codes d'état avec lesquels il est souvent confondu.

Pourquoi une société de proxy aborde la question des codes d'état : nous sommes Geonode et les utilisateurs acheminent leur trafic API par notre intermédiaire ; on nous demande donc souvent si une erreur donnée provient « du proxy ». Pour le code 415, la réponse est pratiquement toujours « non ». Un code 415 provient du serveur d’origine et concerne la requête que vous avez construite. Un intermédiaire peut en générer un dans des circonstances très limitées — un proxy de filtrage inspectant les corps de requête, une passerelle disposant de ses propres règles de contenu — mais cela est rare et est clairement indiqué dans les en-têtes de réponse. Si vous recevez un code 415 via un proxy, supprimez le proxy et vous obtiendrez presque certainement le même code 415 directement. Corrigez la requête. Le seul code d’état qui implique véritablement un proxy est le 407, et son nom l’indique clairement.

Passons maintenant à l’erreur proprement dite.

Ce que dit la spécification

La RFC 9110, section 15.5.16, le définit précisément :

Le code d'état 415 (Type de média non pris en charge) indique que le serveur d'origine refuse de traiter la requête car le contenu est dans un format non pris en charge par cette méthode sur la ressource cible.

Trois éléments de cette phrase sont corrects.

« Le contenu » — le corps de la requête, et non l’URL, ni la chaîne de requête, ni la réponse. Si votre requête ne comporte pas de corps, un code 415 est inhabituel et suggère qu’il y a autre chose.

« Non pris en charge par cette méthode » — la prise en charge s’applique par méthode. Une ressource peut accepter application/json avec la méthode POST et la rejeter avec la méthode PATCH, ce qui est une source de confusion très courante lorsque le même point de terminaison se comporte différemment selon les verbes utilisés.

« Sur la ressource cible » — et par ressource. Le fait qu’un point de terminaison d’une API accepte un format ne vous apprend rien concernant un autre.

La spécification énumère ensuite les causes :

Le problème de format peut être dû au Content-Type ou au Content-Encoding indiqué dans la requête, ou résulter de l’inspection directe des données.

Cette dernière clause est importante et est souvent négligée. Un serveur est autorisé à renvoyer un code 415 après avoir examiné les octets, et pas seulement après avoir lu les en-têtes. Déclarer « Content-Type: application/json » et envoyer un contenu qui n’est pas au format JSON peut légitimement entraîner un code 415 plutôt qu’un code 400.

La RFC précise également ce que le serveur doit vous indiquer. Si le problème concernait l’encodage du contenu, elle stipule que l’en-tête de réponse « Accept-Encoding » « doit être utilisé pour indiquer quels encodages de contenu (le cas échéant) auraient été acceptés ». S’il s’agissait du type de média, l’en-tête « Accept » « peut être utilisé pour indiquer quels types de média auraient été acceptés ». Dans la pratique, les documents MDN indiquent que les serveurs utilisent couramment Accept-Post et Accept-Patch pour les cas spécifiques à une méthode, ce qui est encore plus utile.

Lisez les en-têtes de réponse. Les serveurs vous fournissent souvent la réponse, mais les clients l’ignorent fréquemment.

Les six causes possibles

Classées approximativement par ordre de fréquence.

1. L’absence totale d’Content-Type. Vous envoyez un corps de requête sans jamais en déclarer le format. De nombreux frameworks ne le devineront pas. L’exemple de MDN illustre parfaitement ce cas : une requête POST avec un corps JSON, un en-tête Content-Length et aucun en-tête Content-Type, à laquelle on répond avec les en-têtes 415 et Accept-Post: application/json; charset=UTF-8.

2. L’Content-Type erronée. L’erreur classique consiste à envoyer du JSON tout en déclarant application/x-www-form-urlencoded, généralement parce qu’un client HTTP utilise par défaut l’encodage « form » et que vous avez transmis une chaîne JSON sans la modifier. Le corps est correct ; l’ est erronée.

3. Un type de média proche mais incorrect. text/json au lieu de application/json. application/xml alors que le serveur attend text/xml. Des types propriétaires tels que application/vnd.api+json alors que vous avez envoyé application/json en mode « plain ». Les serveurs stricts effectuent une correspondance exacte et ne feront pas preuve d’indulgence.

4. Problèmes de jeu de caractères. MDN donne l’exemple le plus frappant : envoyer UTF8 alors que le serveur exige UTF-8. Le trait d’union n’est pas facultatif dans le nom enregistré, et un serveur effectuant une validation stricte des paramètres est en droit de le rejeter.

5. Des formats de compression (Content-Encoding) non pris en charge par le serveur. Vous compressez le corps de la requête au format gzip et définissez Content-Encoding: gzip alors que le serveur ne gère que l’encodage d’identité. La RFC prévoit spécifiquement ce cas, et un serveur « bien élevé » devrait renvoyer Accept-Encoding pour vous indiquer ce qu’il attend.

6. Le corps ne correspond pas au type déclaré. En-tête correct, octets incorrects — il s’agit souvent d’un bug de sérialisation, d’un modèle ayant généré une chaîne vide, ou d’un corps ayant subi un double encodage quelque part dans la pile. C’est la clause « inspecter les données directement » qui s’applique ici.

415, 406, 400 et 422

Voici le tableau récapitulatif des codes, et la spécification les distingue clairement.

CodeSignificationDirectionCorrection
415Le format que vous avez envoyé n’est pas pris en chargeCorps de la requêteContent-Type ou Content-Encoding
406Aucune représentation que vous acceptez n’est disponibleRéponseEn-tête Accept
400La requête est mal forméeRequête entièreSyntaxe ou structure
422Format compris, contenu non traitableCorps de la requêteLes données elles-mêmes
413Corps trop volumineuxCorps de la requêteTaille de la charge utile

La différence entre 415 et 406 est une question d’orientation et la plus facile à comprendre une fois expliquée. Le code 415 concerne ce que vous avez envoyé. Le code 406 concerne ce que vous avez demandé à recevoir — la RFC 9110 le définit comme le fait que la ressource ne dispose pas « d’une représentation actuelle qui serait acceptable pour l’agent utilisateur, selon les champs d’en-tête de négociation proactive reçus ». Si vous obtenez un code 406, examinez votre en-tête «Accept», et non votre corps de message.

415 contre 400. La RFC 9110 décrit le code 400 comme le fait que le serveur ne traite pas la requête « en raison d’un élément perçu comme une erreur du client (par exemple, une syntaxe de requête mal formée, un encadrement de message de requête non valide ou un routage de requête trompeur) ». Le code 400 est d’ordre structurel : la requête elle-même est incorrecte. Le code 415 correspond à une requête bien formée dont le corps est dans un format que le serveur n’accepte pas. Dans la pratique, de nombreux serveurs renvoient un code 400 alors qu’un 415 serait plus précis ; vous ne pouvez pas contrôler cela, alors considérez un code 400 sur une requête comportant un corps comme un 415 déguisé.

La distinction entre 415 et 422 est celle que la RFC établit le plus explicitement. La section 15.5.21 précise que le code 422 indique que « le serveur comprend le type de contenu de la requête (par conséquent, un code d’état 415 [Unsupported Media Type] est inapproprié) et que la syntaxe du contenu de la requête est correcte, mais qu’il n’a pas pu traiter les instructions qu’elle contenait ».

La hiérarchie est donc la suivante : 415 signifie que l’enveloppe est incorrecte, 422 signifie que l’enveloppe est correcte mais que le contenu est incorrect. Un JSON bien formé mais auquel il manque un champ obligatoire correspond à un 422. Le même JSON étiqueté comme données de formulaire correspond à un 415.

Diagnostiquer le problème en moins de deux minutes

Une séquence fixe qui permet de résoudre la quasi-totalité des cas.

Première étape : lisez les en-têtes de la réponse. Pas la ligne d'état, mais les en-têtes.

curl -i -X POST https://api.example.com/items \
  -H "Content-Type: application/json" \
  -d '{"name":"test"}'

Recherchez Accept, Accept-Post, Accept-Patch ou Accept-Encoding dans la réponse. Si l’un d’entre eux est présent, cela indique clairement ce que le serveur attend et vous avez terminé.

Étape 2 : vérifiez ce que vous avez réellement envoyé. Pas ce que vous aviez l’intention d’envoyer, mais ce qui a effectivement été transmis. Les bibliothèques clientes ajoutent, remplacent et reformatent les en-têtes, et l’en-tête que vous définissez dans le code n’est pas toujours celui qui a été transmis.

curl -v -X POST https://api.example.com/items \
  -H "Content-Type: application/json" \
  -d '{"name":"test"}' 2>&1 | grep '^>'

Les lignes « > » correspondent à votre requête réelle. Une proportion surprenante de codes d’erreur 415 se résout ici même, lorsque l’en-tête « Content-Type » que vous avez soigneusement défini s’avère avoir été remplacé par une valeur par défaut.

Étape 3 : vérifiez la méthode. Un même point de terminaison peut accepter un type avec la méthode POST et le rejeter avec la méthode PATCH. Testez le même corps de requête avec un verbe différent et voyez si le comportement change.

Étape 4 : vérifiez la chaîne de type exacte. Comparez-la caractère par caractère avec la documentation. application/json par rapport à text/json. UTF-8 par rapport à UTF8. Suffixes propres aux fournisseurs. C’est fastidieux, mais c’est souvent là que se trouve la réponse.

Étape 5 : lisez la documentation relative à ce point de terminaison spécifique. Les API ne sont pas uniformes en interne. Un point de terminaison de téléchargement de fichiers exigeant multipart/form-data au sein d’une API JSON est tout à fait normal.

Résolution du problème côté client

Les cas courants dans les clients courants.

curl. -d implique application/x-www-form-urlencoded, sauf indication contraire. C'est la cause la plus fréquente d'une erreur 415 depuis la ligne de commande :

curl -X POST https://api.example.com/items \
  -H "Content-Type: application/json" \
  -d '{"name":"test"}'

Fetch en JavaScript. Le fait de passer un corps sous forme de chaîne de caractères ne définit aucun Content-Type :

await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "test" }),
});

L’exception à connaître : avec FormData, ne définissez pas vous-même Content-Type. Le navigateur doit le générer car il inclut la limite multipart, et le remplacer entraîne une requête erronée qui se traduit souvent par une erreur 415.

Requêtes Python. Utilisez json= plutôt que data= et l’en-tête est défini automatiquement :

requests.post(url, json={"name": "test"})       # application/json
requests.post(url, data={"name": "test"})       # form-encoded

Axios. Définit application/json pour les objets simples et autre chose pour les chaînes de caractères, ce qui est souvent source de surprises. Si vous avez déjà sérialisé votre charge utile, définissez l’en-tête explicitement. Les différences de comportement entre les clients dans ce cas correspondent exactement au type de sujet que nous avons abordé dans axios vs fetch.

Règle générale : lorsqu’un client propose un paramètre spécifique à JSON, utilisez-le plutôt que de sérialiser manuellement en espérant que l’en-tête par défaut soit correct.

Renvoyer correctement la réponse côté serveur

Si vous êtes du côté client, certains éléments facilitent considérablement l’utilisation de votre API.

Envoyez un en-tête « Accept-Post » ou « Accept-Patch » avec le code 415. La RFC préconise « Accept » ou « Accept-Encoding » ; les variantes spécifiques à chaque méthode sont plus précises et MDN les documente précisément pour cet usage. Cet en-tête unique transforme une session de débogage en un coup d’œil.

Incluez un corps lisible. Un code d’état avec un corps vide oblige le client à deviner. Indiquez ce que vous avez reçu et ce que vous attendiez.

Distinguez correctement le code 415 du code 422. Si vous avez compris le type de contenu et que le corps a été analysé mais que la validation a échoué, il s’agit d’un 422. Renvoyer un 415 pour des échecs de validation incite les utilisateurs à vérifier leurs en-têtes alors que ceux-ci sont corrects ; c’est une erreur courante et coûteuse dans la conception d’API.

Faites preuve de souplesse concernant les paramètres lorsque cela est possible sans risque. Refuser application/json; charset=utf-8 alors que vous acceptez application/json est techniquement défendable, mais pratiquement inutile. Analysez correctement le type de média et ignorez les paramètres qui ne vous intéressent pas.

N’utilisez pas le code 415 comme rejet générique. Il a une signification spécifique. Le surcharger rend votre API plus difficile à utiliser et fausse la logique de réessai côté client.

Quand un code 415 n'est pas vraiment un 415

Cas où le code d'état induit en erreur.

Une passerelle ou un WAF a rejeté la requête. Certaines couches de sécurité renvoient un code 415 pour les corps de requête qu’elles jugent suspects, quel que soit le type de contenu réel. L’indice réside généralement dans un corps de réponse qui ne semble pas provenir de l’application, ou dans des en-têtes identifiant un intermédiaire.

Une valeur par défaut du framework s’est déclenchée avant l’exécution de votre code. De nombreux frameworks web rejettent les types de contenu inconnus au niveau du middleware. Votre gestionnaire ne s’est jamais exécuté ; par conséquent, aucun élément de la logique de votre application n’est pertinent pour la résolution du problème.

Un équilibreur de charge ou un CDN a supprimé un en-tête. C’est rare, mais cela arrive. Si la requête fonctionne lorsqu’elle est envoyée directement et échoue via l’infrastructure, comparez les en-têtes aux deux extrémités avant de supposer que l’application a changé.

Le point de terminaison n’existe pas. Certains serveurs répondent à une route non correspondante lors d’une requête POST par un code 415 plutôt que 404, car la négociation du type de contenu a lieu avant que le routage ne soit résolu. Vérifiez l’URL.

La redéfinition de la méthode HTTP a échoué. Si votre framework prend en charge la redéfinition de la méthode via un en-tête ou un paramètre de requête, la méthode effective peut ne pas être celle que vous avez envoyée, et la prise en charge du type de contenu dépend de la méthode.

Dans chacun de ces cas, la solution se trouve en amont de votre charge utile. Le principe général est le suivant : si la requête est manifestement correcte et que le code d’état 415 persiste, cessez de modifier le corps de la requête et commencez à identifier quel composant du chemin d’accès génère cette réponse.

Questions fréquentes

Que signifie l'erreur 415 « Unsupported Media Type » ?

Le serveur a rejeté la requête car le format du corps de la requête n'est pas pris en charge pour cette méthode sur cette ressource. La norme RFC 9110 attribue cette erreur à l'en-tête « Content-Type », à l'en-tête « Content-Encoding » ou au fait que le serveur inspecte directement le corps de la requête. Cela concerne le format de ce que vous avez envoyé, et non l’exactitude des données.

Comment corriger une erreur 415 ?

Vérifiez d’abord les en-têtes de réponse : les serveurs renvoient souvent Accept, Accept-Post ou Accept-Encoding en précisant exactement ce qu’ils attendent. Vérifiez ensuite ce que votre client a réellement transmis, car les bibliothèques peuvent remplacer les en-têtes. La solution la plus courante consiste à ajouter Content-Type: application/json à une requête qui n’en comportait pas.

Quelle est la différence entre les codes 415 et 400 ?

Le code 400 signifie que la requête est mal formée — syntaxe ou structure incorrecte. Le code 415 signifie que la requête est bien formée, mais que le corps est dans un format non pris en charge. Dans la pratique, les serveurs renvoient souvent un code 400 alors qu’un 415 serait plus précis ; il convient donc d’examiner de plus près un code 400 sur une requête comportant un corps, car il peut s’agir d’un problème lié au type de contenu.

Quelle est la différence entre les codes 415 et 422 ?

La RFC 9110 établit clairement cette distinction : le code 422 signifie que le serveur a compris le type de contenu et que la syntaxe était correcte, mais qu’il n’a pas pu traiter les instructions. Ainsi, le code 415 indique que l’enveloppe est incorrecte, tandis que le code 422 indique que le contenu est incorrect. Un JSON valide dans lequel il manque un champ obligatoire entraîne un code 422.

Pourquoi obtiens-je un code 415 lors du téléchargement de fichiers ?

Généralement parce que l’en-tête Content-Type a été défini manuellement sur une requête multipart. Le navigateur ou le client doit générer cet en-tête lui-même, car il contient la limite multipart. Le définir manuellement supprime cette limite et génère une requête que le serveur ne peut pas analyser.

Un proxy peut-il provoquer un code 415 ?

Rarement. Le code 415 provient du serveur d’origine et concerne le corps de votre requête. Un proxy filtrant ou une passerelle inspectant le contenu peut en générer un, mais le code d’état spécifique aux proxys est généralement le 407, comme son nom l’indique. Effectuez un test sans le proxy : si le code 415 persiste, le proxy n’est pas en cause.

Le code 415 signifie-t-il que mon JSON n’est pas valide ?

Pas nécessairement. Si le serveur a rejeté le type de contenu, votre JSON n’a jamais été examiné. Si le serveur a déclaré le bon type puis a constaté que le corps n’était en réalité pas de ce format, alors oui — la RFC autorise le rejet après « inspection directe des données ». Vérifiez d’abord le problème d’en-tête ; c’est un cas bien plus courant.

Dois-je réessayer après un code 415 ?

Non. Il s’agit d’une erreur client et la même requête produira le même résultat. Réessayer gaspille des requêtes et, si vous êtes soumis à une limitation de débit, peut aggraver la situation. Corrigez le type de contenu et envoyez la requête une seule fois.

En résumé

Le code 415 a une signification précise et restreinte : le conteneur de vos données n'est pas celui que ce point de terminaison accepte pour cette méthode. Il ne s'agit pas d'une invalidité de vos données, ce à quoi sert le code 422, ni de ce que vous avez demandé de recevoir, ce à quoi sert le code 406.

Comme la signification est précise, le diagnostic est rapide. Lisez les en-têtes de réponse, car un serveur bien conçu indique les types acceptables dans les en-têtes « Accept », « Accept-Post » ou « Accept-Encoding ». Vérifiez ensuite ce que votre client a réellement envoyé sur le réseau plutôt que ce que vous lui avez demandé, car les valeurs par défaut et les intergiciels remplacent souvent l’en-tête que vous avez défini. Entre ces deux étapes, vous résoudrez la plupart des cas sans même toucher au corps de la requête.

Et si la requête semble irréprochable et que le code 415 persiste, la réponse ne provient probablement pas de l’application que vous pensez. Les passerelles, les middlewares de framework et les routes non correspondantes génèrent tous des erreurs 415 qui n’ont rien à voir avec votre charge utile — à ce stade, la question pertinente n’est pas de savoir quoi modifier, mais quel composant du chemin répond à la requête.