I would go with 409: Conflict
, because what you have is a violation of resource state.
405: Method Not Allowed
would also work. If you’d want to use a 405
, you’d have to send an Allow
header to indicate the supported methods, and the supported methods would vary depeding on the resource’s state. In my opinion, this response code fits well for read-only resources, resources that can’t be deleted etc. but Darrel’s comments to this post are valid. The spec is ambiguous:
The method specified in the Request-Line is not allowed for the
resource identified by the Request-URI. The response MUST include an
Allow header containing a list of valid methods for the requested
resource.
In either case, you should provide information in the response body for the client to understand the source of the error.
Regarding the other two methods mentioned:
403: Forbidden
should be used when you don’t have the appropriate privileges to modify the resource, i.e. if you have to be an admin to delete that resource and you’re not.
412: Precondition Failed
is mostly used for conditional requests where the preconditions are specified explicitly in the request headers. For example, you can have conditional PUT requests that should be carried out only when the If-Match
header is valid. If you don’t specify anything in the request headers, I’d still choose 409 over 412. Here’s the spec for 412:
The precondition given in one or more of the request-header fields
evaluated to false when it was tested on the server. This response
code allows the client to place preconditions on the current resource
metainformation (header field data) and thus prevent the requested
method from being applied to a resource other than the one intended.