If the request could not be correctly parsed (including the request entity/body) the appropriate response is 400 Bad Request [1].
RFC 4918 states that 422 Unprocessable Entity is applicable when the request entity is syntactically well-formed, but semantically erroneous. So if the request entity is garbled (like a bad email format) use 400; but if it just doesn't make sense (like @example.com
) use 422.
If the issue is that, as stated in the question, user name/email already exists, you could use 409 Conflict [2] with a description of the conflict, and a hint about how to fix it (in this case, "pick a different user name/email"). However in the spec as written, 403 Forbidden [3] can also be used in this case, arguments about HTTP Authorization notwithstanding.
412 Precondition Failed [4] is used when a precondition request header (e.g. If-Match
) that was supplied by the client evaluates to false. That is, the client requested something and supplied preconditions, knowing full well that those preconditions might fail. 412 should never be sprung on the client out of the blue, and shouldn't be related to the request entity per se.
422
is the answer. The accepted answer below is wrong. HTTP status codes are a mess, but devs around the world have thought about this long and hard and selected422
, not because it's great, but because it's the best we have. Avoid403
,409
,412
etc. These have very specific technical meanings and should not be used for other things.409
for example is for write/merge conflicts and should prompt the client to show some screen saying 'oops, someone else edited this record in the mean time` and give you a diff screen or something. – Stylobate