Code change:
10.3. <del> The HTTP/2 field block encoding allows the expression of names that are not valid field names in HTTP.  Requests or responses containing invalid field names MUST be treated as malformed.  An intermediary therefore cannot translate an HTTP/2 request or response containing an invalid field name into an HTTP/1.1 message. Similarly, HTTP/2 allows field values that are not valid.  While most of the values that can be encoded will not alter header field parsing, carriage return (CR, ASCII 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII 0x0) might be exploited by an attacker if they are translated verbatim.  Any request or response that contains a character not permitted in a field value MUST be treated as malformed.  Valid characters are defined by the ABNF rule in HTTP. </del> <ins> HPACK permits encoding of field names and values that might be treated as delimiters in other HTTP versions.  An intermediary that translates an HTTP/2 request or response MUST validate fields according to the rules in HttpHeaders roles before translating a message to another HTTP version.  Translating a field that includes invalid delimiters could be used to cause recipients to incorrectly interpret a message, which could be exploited by an attacker. An intermediary can reject fields that contain invalid field names or values for other reasons, in particular those that do not conform to the HTTP ABNF grammar from HTTP.  Intermediaries that do not perform any validation of fields other than the minimum required by HttpHeaders could forward messages that contain invalid field names or values. </ins> 10.4.

Related discussion:
text: Many Implementations will ultimately end up double validating field names: once to exclude the s in their h2 layer and then later in their semantic layer to include only the s. Double validation could be avoided if this document either didn't restrict field validity or precisely defined valid fields as a subset of s so that semantic layers could trust the fields received from their h2 layers as being valid HTTP. Maybe there is a reason for this double validation and the resulting CPU cycles, but I have yet to see why validity is only partially defined.
It suggests it but does not require it. The other text requires validation. Most intermediaries will not apply the full ABNF validation because a) it requires perfect understanding of the ABNF of all header fields, which they will not have, and b) even if they did, the -semantics ABNF is sufficiently costly to validate that they won't do it. Cheaper validation steps are more likely to be implemented. This document (and -semantics) is imprecisely defining them because a . The ABNF you're citing represents, fundamentally, guidance. If you want to reject things that don't conform to the ABNF you are free to do so (as -semantics says), but there is no document that obligates you to reject them. This is deliberate, because there is (IMO) absolutely no point in adding normative requirements that, if followed, would harm interoperability. In this case the document is calling out specific cases that MUST be rejected. Practically speaking the intention of this is to encode requirements from other messaging formats, such as -messaging, to ensure that HTTP/2 implementations do not encode header fields that cannot be safely translated to HTTP/1.1. This provides a lower bound on validation: so long as everybody does this, we can safely rely on HTTP/2 messages being represented in HTTP/1.1's framing. Note that this doesn't meant they'll be valid HTTP/1.1 messages, just that they are not going to parse incorrectly. With that in mind, the constraints added here are, in order: A cheap bitwise check that can be safely vectorised and applied to reject most invalid field names. This is sufficient to get close to the ABNF, but is cheaper. A check that reserves pseudo-headers and is a single-byte comparison.