Http codes has nothing to be with business (validation) errors. Some ppl use HTTP error codes to encode their catatalog of errors. But I don't think it's a good practice.
Http errors are related to the protocol (http). So any business exception thrown by your code, should be (in my oponion) handled and returned as a missage. And of course into a 200 Http respone.
Runtime Exceptions (unexpected errors) can be returned as Http 500 unless you want to control every possible runtime exception, handle it and transform it into a controlled error message (in such case, response will be Http 200).
An error 500 means unrecovery error. The business can not continue, there's no alternative flow, so end of the request and your request has not been processed.
I prefer to define a complex respone message: header, body, attributes, ... And also a inner code that it doesn't follow Http response codes. If code is informed , server is notifying something beside the result of the executed process.
The only codes I would reuse from HTTP catalog, would be:
200: request processed and respone sent. If the business process finished successfuly or not doesn't matter. We got the request and we were able to perform validations, processes, etc. For more info check out response messge.
500: Any unexpected error. Something wrong happened. It's not related to the business, it might be something eventual. However the business process finished premsturaly. Client doesn't need to know what happened. We may be giving too much info about our system. So let error go as 500. Let client to deal with.
403: Forbbiden access (and this one, not always. Only if there's no special business at client side).
Otherwise you are coupling protocol responses with business responses. Then, client side, may fall into error of unexpected redirections, unexpected end of flows executions, ...
Edit: So far, there's standard to follow. Any stratgey is right if it fit in your requirements