Solving the conflict of using the HTTP status 409
Tags: restful, rest, statuscodes, http
Published: 2020-12-18 13:58:22

---
title: Solving the conflict of using the HTTP status 409
published: true
description: On some tips of when to use this status, and when it might seem a good practice to do so.
tags: RESTful, REST, statuscodes, HTTP
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/d6oyo2jqpv1kx1cep50i.jpg)
---
I've probably seen [this status code](https://tools.ietf.org/html/rfc7231#section-6.5.8) for the first time today, in an assignment submitted by a student. It's defined as [409 conflict](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409). The corresponding RFC indicates that

> ... the request could not be completed due to a conflict with the current state of the target resource

Despite a [bunch](https://stackoverflow.com/questions/17076349/edit-conflicts-and-409-vs-412-responses) [of](https://stackoverflow.com/questions/45063805/distinguishing-http-status-code-403-and-409-in-practice-or-400) [questions in Stackoverflow](https://stackoverflow.com/questions/50946698/422-or-409-status-code-for-existing-email-during-signup) (and answers) there's no real consensus on when to *actually* use it as opposed to the other options indicated in the answers: 403, 412 or even 422.

Let's see first to which verb it should respond to. The RFC says:

>... Conflicts are most likely to occur in response to a PUT request. 

But, [PUT should be used when we want to modify a resource](https://restfulapi.net/rest-put-vs-post/) *under the supplied URI*. So where's the conflict? Here's the state I want, take it, whatever was there before, just forget it. If there's a conflict with existing state (whatever that is), we're explicitly telling the system to *solve* that conflict by adopting this new state.

Things are never so simple, however. My point here is that `PUT` is rather imperative. If you want the system to create a resource out of what you're supplying, [`POST`](https://developer.mozilla.org/es/docs/Web/HTTP/Methods/POST) is quite possibly a better match, since you're submitting some data and telling the system to create a resource out of it. The system might say: well, not possible, here's your 409 status (with an informative message, of course, as the spec says).

And yet, 409 is used all the time with PUT requests. [WebDAV returns 409](https://stackoverflow.com/questions/7780264/webdav-409-error) when you're trying to upload a file that's older than the one it's trying to substitute or there's no collection properly set up for it.

> It might be questionable the use of PUT here, since idempotency is not really guaranteed: the state of the _directory_ is going to be changed. But that's what's used.

In some other cases, [it's returned when something is not recognized](https://github.com/mike-levenick/mut/issues/43). In both cases (and some other you might think of), there's no real conflict anywhere. You're trying to upload a file to somewhere you shouldn't, well, unauthorized 403 might be it. There's some error in the way you put the data together, that's no doubt a [bad request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400). Where's the conflict?

There might be an actual use case for 409, right?

## Proposed best practice for 409 conflict

When you use PUT, you create a resource with the data that's *in the URI or in the body*. But there's some metadata you should take into account, too. The one that goes in the header, which goes from MIME Types to [ETags](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) to custom headers. 

And here's the thing: those custom headers might be *in conflict* with the actual data that's contained there. That's actually one of the things that WebDAV does: there's a custom version header, and that version has to increase if you don't want the new state to be *in conflict* with the state it substitutes. The spec for 409 also indicates that the user should be able to do something about the data: in the case of a custom header, the client needs to have a *good* representation of the state; if it does not, there will be a conflict.

But a header is, in general, a meta-state, that is, not exactly part of the metadata, but rather part of the data we have about that data. What we're proposing here is actually to use 409, then, when *there's a conflict between the desired or existing state and their metadata*. That's a more precise definition (and use case) than simply "a conflict in the state".

So I guess this kinda solves the conflict.