What is the most appropriate HTTP status code to return if a required header is missing?

400 Bad Request

It's a user error in the request. Unlike with a 403, the client should be allowed to repeat their request, but only after modification:

10.4.1 400 Bad Request The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

Edit

As Mark Reed points out in the comments, a 403 says, "There is nothing wrong with what you sent me. You have proper authorization and the syntax was valid. I just don't want to do what you ask."

The part that you have in bold simply says, if the server so chooses, it can tell the client exactly why it doesn't want to fulfill the request.