Code change:
MUST NOT forward fields that contain any of the values that are listed as prohibited above. <del> A recipient MAY treat a message that contains a field name or value that includes other characters disallowed by HTTP and HTTP as malformed. When a request message violates one of the requirements above, it SHOULD be responded to using the 400 (Bad Request) status code (HTTP) before the stream is reset, unless a more suitable status code is defined, or the status code cannot be sent (e.g., because the error occurs in a trailer field). Note that field values that are not valid according to the definition of the corresponding field do not cause a request to be malformed; the requirements above only apply to the generic syntax for field values as defined in HTTP. </del> <ins> When a request message violates one of these requirements, an implementation SHOULD generate a HTTP, unless a more suitable status code is defined or the status code cannot be sent (e.g., because the error occurs in a trailer field). </ins> 8.2.2.

Related discussion:
text: But whether your cookie header field comes from H1/H2/H3, it will have to pass through the exact same validity checks. What is certain is that these HTTP syntax checks must be performed somewhere. But the messaging layer is not always exactly the best place for this. Typically an H1 implementation will not have code to check for embedded LF characters because it's a delimiter, while H2 needs to have explicit check against this. The rules on the resulting cookie header field format apply after Cookie header reassembly, not before. And this reassembly is specific to the messaging layer which defines how to serialize fields. Last, the generic rules are not sufficient to safely reassemble the pseudo-header fields. Maybe in the end we could combine our two parts, starting with yours to indicate what every HTTP implementation must do, and putting the focus on the extreme care that is required when translating to HTTP/1-like since we know that it's one of the most natural approaches (and even used in the examples in the spec). This could give roughly: With this I think it that the intent is clear, the guidance as well, it is exhaustive and doesn't leave any doubt on what needs to be done.
Oh, and of course: :-)
I think extreme care is need anytime a HTTP message is represented, not just when represented as a HTTP/1. If a H2 layer is delivering messages to a semantic layer that was developed against h1, then it will not be assuming HTTP valid charset in no matter if the message is passed as byte streams or lines or XML or JSON or Strings in classes. It seams wrong for one particular messaging layer (h2) to require changes in transport impartial HTTP semantic layers so the messaging layer can be "abused" for non HTTP purposes? As you say, the actual syntax validations needed to be done are dependent on the messaging layer. So they are best done in the messaging layer as it knows what it is and can sometimes do things efficiently like checking charsets during parsing. If the syntax is not validated by the messaging layer, then the semantic layer will have to do full validation, which will result in wasting CPU duplicating any checks that are done by the messaging layer (or are intrinsic to the transport).
I think I'm OK with this.