DEV Community

Cover image for Solving the conflict of using the HTTP status 409
Juan Julián Merelo Guervós
Juan Julián Merelo Guervós

Posted on • Edited on

Solving the conflict of using the HTTP status 409

I've probably seen this status code for the first time today, in an assignment submitted by a student. It's defined as 409 conflict. 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 of questions in Stackoverflow (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 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 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 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. 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. Where's the conflict?

There should 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 through ETags 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 data, 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.

Top comments (0)