409 Conflict
Utilisation
Lorsqu’une erreur 409 Conflict survient, la requête est valide mais ne peut pas aboutir en raison d’une incohérence d’état. Par exemple, le client répond à un message entre-temps supprimé, et la ressource cible n’est plus dans un état compatible. Le serveur renvoie ce statut pour signaler le conflit.
Remarque
409 Conflict signifie que la requête est bien formée mais entre en conflit avec l’état actuel de la ressource (mise à jour concurrente, création en double). 422 Unprocessable Content signifie que le corps de la requête est syntaxiquement valide mais sémantiquement invalide (règles de validation non respectées). 400 Bad Request signifie que la requête elle-même est mal formée (corps impossible à analyser, en-têtes invalides). 409 concerne les conflits d’état, 422 la validation, 400 la syntaxe.
Le client est censé examiner le corps du message pour déterminer comment résoudre le problème. Dans le cas d’une réponse à un message supprimé, le client choisit d’abandonner la requête, de restaurer l’ancien fil, ou de créer un nouveau fil citant le texte précédent. Cette action relève entièrement de la responsabilité du client, selon les exigences ou les politiques définies par le serveur.
Impact SEO
Les moteurs de recherche comme Google n’indexent pas une URL renvoyant un statut 409. Les URL précédemment indexées qui renvoient ce code de statut sont retirées des résultats de recherche.
Exemple
Le client tente d’associer un « like » à un billet de blog existant portant « ID = 111 ». Le serveur répond pour indiquer que le billet a été gelé et n’accepte plus ni réponses ni étiquettes.
Requête
POST /blog/update?postid=111&flag=like HTTP/1.1
Host: example.com
Réponse
HTTP/1.1 409 Conflict
Content-Type: text/html
Content-Length: 288
<html>
<head>
<title>Blog Entry Frozen</title>
</head>
<body>
<p>This post has been marked read-only. To post
a reply or tag, change the status and try
again.</p>
</body>
</html>
Comment corriger
Un 409 Conflict signifie que la requête entre en conflit avec l’état actuel de la ressource sur le serveur.
Récupérez l’état actuel de la ressource avant de réessayer. Envoyez une requête GET pour obtenir la dernière version. L’état de la ressource a changé depuis la dernière lecture des données par le client. Comparez l’ETag ou le champ de version renvoyé avec la valeur détenue par le client.
Utilisez des en-têtes conditionnels pour détecter les conflits. Incluez If-Match avec la valeur d’ETag actuelle dans les requêtes PUT et PATCH. Le serveur rejette la requête lorsque l’ETag ne correspond plus, ce qui évite les écrasements à l’aveugle. Ce schéma s’appelle le contrôle de concurrence optimiste.
PUT /api/resource/42 HTTP/1.1
If-Match: "abc123"
Content-Type: application/json
{"name": "updated value"}
Le serveur répond 409 lorsqu’un autre client a modifié la ressource entre le GET et le PUT.
Fusionnez les modifications ou implémentez une logique de résolution de conflits. Comparez les modifications voulues par le client avec l’état actuel du serveur. Appliquez une stratégie de fusion : le dernier écrit l’emporte, fusion champ par champ, ou invitation de l’utilisateur final à arbitrer les différences. Les API dotées d’un champ de version ou de révision dans la charge utile imposent au client d’inclure le numéro de version actuel dans la requête de mise à jour.
Résolvez les conflits de ressources en double. Lors de la création d’une ressource avec POST ou PUT, le serveur renvoie 409 si une ressource portant le même identifiant unique existe déjà. Vérifiez l’existence d’entrées préalables avant la création et utilisez une clé d’idempotence pour éviter les créations en double lors des nouvelles tentatives.
Traitez les conflits au niveau de la base de données. Les serveurs applicatifs adossés à une base de données renvoient 409 lorsqu’une contrainte d’unicité, une contrainte de clé étrangère ou un verrou au niveau de la ligne empêche l’opération. Le corps de la réponse inclut souvent le nom précis de la contrainte. Résolvez le conflit de données sous-jacent (clé en double, enregistrement parent manquant, transaction concurrente) avant de réessayer.
Pour les systèmes de gestion de versions, récupérez la dernière version et réappliquez les modifications. Récupérez la révision la plus récente, réconciliez les différences et resoumettez la mise à jour. Les API basées sur Git (GitHub, GitLab) renvoient 409 lorsqu’un push entre en conflit avec des modifications amont.
Inspectez le corps de la réponse pour connaître les détails du conflit. Le serveur inclut généralement des informations expliquant l’incohérence : le champ en conflit, la valeur actuelle ou la version attendue. Utilisez ces données pour déterminer la bonne voie de résolution.
Implémentez une logique de nouvelle tentative avec rafraîchissement de l’état. Pour les clients automatisés, construisez une boucle de reprise : récupérer le dernier état de la ressource, réappliquer la modification voulue et resoumettre. Ajoutez un backoff exponentiel pour éviter de surcharger le serveur en conditions de forte concurrence.
Références de code
.NET
HttpStatusCode.Conflict
Rust
http::StatusCode::CONFLICT
Rails
:conflict
Go
http.StatusConflict
Symfony
Response::HTTP_CONFLICT
Python3.5+
http.HTTPStatus.CONFLICT
Java
java.net.HttpURLConnection.HTTP_CONFLICT
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_CONFLICT
Angular
@angular/common/http/HttpStatusCode.Conflict