HTTP status codes belong to the transfer of documents over a network domain, not to the domain the documents are about.
For example, if I have a document that describes whether the password "walrus" complies with some policy, I might try to retrieve that document with a request like
GET /policy?password=walrus
The document returned to me might be an explanation that the "walrus" is compliant with the policy, or it might be a list of policy violations. But in the transfer of documents domain, the response to the query is a current representation of the document, and therefore the appropriate status code is 200.
400 would NOT be appropriate, because that code indicates that (a) the message body of the response is a representation of an explanation of an error (rather than being a copy of the document we asked for) and (b) more precisely indicates that the request was improperly formed.
More generally, a successfully retrieved document that explains that you are not on your domain's happy path is still a successfully retrieved document, and should get a 2xx status code, just the same as if you were simply downloading a web page about that password from a website.
There are more possibilities when you are sending changes to the server, rather than fetching information from it.
POST /e363c9c3-03a9-43fa-9e1c-fe5cad95fb04 HTTP/x.y
Content-Type: application/x-www-form-urlencoded
action=changePassword&password=walrus
Here, it is perfectly reasonable to report a client error, on the grounds that the payload is supposed to be a changePassword
message, and "walrus" is semantically nonsense as a value in the message because it violates policy. So 422 Unprocessable Entity might be an option, or 409 Conflict, or 403 Forbidden -- all valid ways of announcing to the transfer of documents over a network domain that the request is unsatisfactory.
Imagine a puzzle game, like mastermind, where the player tries to solve the puzzle. Such a request might look like
POST /puzzles/59bfc5a5-8e5b-4bf9-b6fd-52c7b3634b3c HTTP/x.y
Content-Type: application/x-www-form-urlencoded
guess=red,blue,blue,white
Even when this guess is "wrong", it's still a valid request within the game domain; the game itself updates, the player gets hints, a row of the decoding board is consumed, and so on. A 2xx success code is still appropriate even though the player didn't win the game.
POST /puzzles/59bfc5a5-8e5b-4bf9-b6fd-52c7b3634b3c HTTP/x.y
Content-Type: application/x-www-form-urlencoded
guess=red,blue,blue,walrus
Here, we'd return a 422, because the request itself is broken (walrus is "semantically erroneous" in this context).