Change:
not possible, unless this is otherwise permitted (e.g., idempotent actions like GET, PUT, or DELETE). <ins> 4.1.3. A malformed request or response is one that is an otherwise valid sequence of frames but is invalid due to the presence of extraneous frames, prohibited header fields, the absence of mandatory header fields, or the inclusion of uppercase header field names. A request or response that includes a payload body can include a "content-length" header field.  A request or response is also malformed if the value of a content-length header field does not equal the sum of the DATA frame payload lengths that form the body. A response that is defined to have no payload, as described in Section 3.3.2 of RFC7230 can have a non-zero content-length header field, even though no content is included in DATA frames. Intermediaries that process HTTP requests or responses (i.e., any intermediary not acting as a tunnel) MUST NOT forward a malformed request or response.  Malformed requests or responses that are detected MUST be treated as a stream error (errors) of type HTTP_GENERAL_PROTOCOL_ERROR. For malformed requests, a server MAY send an HTTP response prior to closing or resetting the stream.  Clients MUST NOT accept a malformed response.  Note that these requirements are intended to protect against several types of common attacks against HTTP; they are deliberately strict because being permissive can expose implementations to these vulnerabilities. </ins> 4.2. The pseudo-method CONNECT (RFC7231, Section 4.3.6) is primarily used

Discussion:
by importing the RFC7540 malformed request/response text. This section is general enough, it doesn't appear to have much in the way of difference between HTTP/2 and HTTP/3. Are there things we should trim out, or conditions that we need to spell out in more detail?
This issues arises from some off-list discussion on how to build up a header list, and who is responsible for validating the result. The conclusion is that the application is responsible for doing so. In HTTP/2, RFC 7540 section 8.1.2.6 explains how an endpoint should handle malformed requests or responses. There is no explicit link to this in H3, only implicitly via references to topics in 8.1.2.*. However, I think some of that guidance is not applicable: the one that sticks out is this: if the value of a content-length header field does not equal the sum of the DATA frame payload lengths that form the body.
Some further info. In H2, malformed request/response causes a stream error of type PROTOCOLERROR. The H3 draft says: No single mapping. See new HTTPMALFORMEDFRAME error codes defined in Section 8.1. But errors in the category of malformed request/response may not caused by a problem with the frames themselves. Fortunately, we have H3 HTTPGENERALPROTOCOLERROR, which seems like the correct thing to use in this case. But nowhere in the draft is this ever referred to, so its easy to miss.
FRAME related errors are defined at the end of S8.1. However that is going to change due to
Nice catch! I think I'd prefer using HTTPGENERALPROTOCOLERROR or an error code just for this purpose rather than HTTPMALFORMEDFRAME, because this is a framing error in the HTTP semantic layer, rather than an error in a HTTP/3 frame. The issue with using HTTPMALFORMEDFRAME becomes most apparent when the request body is shorter than the sum of DATA frames, and if there is a trailer. Then, the error will be detected when seeing the HEADERS frame. It would be strange to report the issue as HTTPMALFORMEDFRAME(HEADERS) (because it's not an issue with the HEADERS frame), or as HTTPMALFORMED_FRAME(DATA) (because none of the DATA frames that the client sent was malformed.

^^ this comment is about an endpoint abruptly closing a stream rather than an endpoint detecting the peer abruptly closing a stream. Taking back the comment, as I think it deserves a separate issue.
Another error that we saw a lot in the early days of H2 deployment was headers fields using mixed-case capitalization. This cannot be attributed to a malformed H3 frame. I really hope this class of error has been shaken out of systems by now but you never know.
NAME Agreed. I think using HTTPGENERALPROTOCOL_ERROR as a catch-all error code when the peer does something stupid makes sense. After all, that's what we did in H2 and IMO it works well.
I think this falls under the umbrella of making sure RFC7540 content is referenced / restated appropriately in an H3 world.
Maybe it's worth noting that HTTPGENERALPROTOCOLERROR is the error that a proxy is expected to send when upstream resets a HTTP message (e.g., h1 connection being closed in middle of a T-E chunk, receiving RSTSTREAM on a h2 stream). We could have an error code dedicated to that, but H2 has not had one and therefore I do not think there's a strong necessity to have a dedicated codepoint.
Discussed in London; restate them with care.