I like the header idea, and it has some advantages (can be processed without ANY dependency on the JSON payload / etc) but it also has some downsides (how can you determine whether the sender is authorized to send errors to a given endpoint?) and I would recommend to keep error reports that reflect business logic (required properties, permission errors, etc) more closely to the domain of ActivityPub and use a Reject activity instead, as @trwnh proposed.
The current norm among implementors (regardless of whether they already have the key or not) is to process HTTP signatures synchronously and AP payloads asynchronously. I think this provides a clean and natural separation for which type of errors are reported using which framework (signature errors with status code and immediate message, which helps developers implementing it for the first time, and AP payload errors using Reject, because they’re more likely to be usage-based errors that should be reported to a user, like insufficient permissions to reply to a post, rather then developer compatibility errors)
Alternatively I could see trying to draw some sort of separation between errors that should be reported to a user (using Reject) and errors that should be reported to a developer (using a header), but that sounds like a very difficult distinction for an implementor to maintain and, anyway, users should have visibility into when they’re unable to communicate with a given remote server because of an incompatibility so that they can raise the issue with their software’s developers.