Change:
control stream MUST be treated as a connection error of type HTTP_WRONG_STREAM. <del> PRIORITY frames received by a client MUST be treated as a stream </del> <ins> PRIORITY frames received by a client MUST be treated as a connection </ins> error of type HTTP_UNEXPECTED_FRAME. 4.2.4.

Discussion:
Has this been the only case where a protocol violation resulted in a stream error? Or should we check if there are similar cases and file PRs as necessary? I ask this, because IIUC at least some of us considered the proposal as a change of design principle, to stop localizing such errors, and I wonder if the change made in this PR is a tip of an iceberg.
I haven't comprehensively reviewed the draft, but having just implemented the HTTP/3 frame parser, I can say that other UNEXPECTED_FRAME instances are connection errors. Furthermore, PRIORITY frames can arrive on the control stream. If there were a stream error there it would have to take down the connection anyway.
NAME that's a good question. Previously, the philosophy has been that connection errors are ones which screw up the state so badly you can't trust the connection to proceed correctly. It's a reasonable, but not bulletproof, argument that a peer which doesn't obey the protocol has the same implication -- you can't trust the connection. If you see other protocol violations which are stream-local errors, please file issues and we'll discuss.
For consistency with PR and on-list discussion, there are multiple other places in the draft an error that indicates an incorrect implementation is treated as a stream error, not a connection error. "Only servers can push; if a server receives a client-initiated push stream, this MUST be treated as a stream error of type HTTPWRONGSTREAMDIRECTION." "A PRIORITY frame received after other frames on a request stream MUST be treated as a stream error of type HTTPUNEXPECTEDFRAME." Unclear: "A PRIORITY frame that references a non-existent Push ID, a Placeholder ID greater than the server's limit, or a Stream ID the client is not yet permitted to open MUST be treated as an HTTPLIMITEXCEEDED error." "A CANCELPUSH frame is sent on the control stream. Receiving a CANCELPUSH frame on a stream other than the control stream MUST be treated as a stream error of type HTTPWRONGSTREAM." Possibly should be a connection error: "A PRIORITY frame sent on a request stream with the Prioritized Element Type set to any value other than "11" or which expresses a dependency on a request with a greater Stream ID than the current stream MUST be treated as a stream error of type HTTPMALFORMEDFRAME."

In the appendix: " SETTINGSMAXCONCURRENTSTREAMS: QUIC controls the largest open Stream ID as part of its flow control logic. Specifying SETTINGSMAXCONCURRENTSTREAMS in the SETTINGS frame is an error. SETTINGSINITIALWINDOWSIZE: QUIC requires both stream and connection flow control window sizes to be specified in the initial transport handshake. Specifying SETTINGSINITIALWINDOWSIZE in the SETTINGS frame is an error. SETTINGSMAXFRAMESIZE: This setting has no equivalent in HTTP/3. Specifying it in the SETTINGS frame is an error."
I'm ok with such changes but wonder if we should also add some further prose to the document that: highlights HTTP/3 difference to HTTP/2 i.e. "all errors are always connection errors" captures some of the guidance mentioned elsewhere like "identifying the stream on which a problem frame was delivered may be useful in error analysis, endpoints might want to include the stream ID in the reason phrase"
NAME I'd forgotten about the settings appendix. This reads weird. Those settings are not formally defined in core HTTP/3 by name, so I wonder if the intention is that it is a "philosophical error". The code points are reserved, so we could suggest connection error on receipt. But we also have reserved grease code points that must be ignored.
I don't believe all errors are connection errors, even after Kazuho's PR, but I believe we could make that true with some changes. For example, when too large a header is received, it's currently a stream error because it's not required you communicate your max header size, and if you don't, the peer can't expected to know the limit.
The default value of SETTINGSMAXHEADERLISTSIZE is unlimited. Would you expect a peer to generate an excessive load error on a stream with the default?
The current text is: "encountering a larger message header SHOULD be treated as a stream error of type "HTTPEXCESSIVELOAD". If an implementation wishes to advise its peer of this limit, it can be conveyed as a number of bytes in the "SETTINGSMAXHEADERLISTSIZE" parameter." To me, the issue here is that a peer can have a limit, but is not required to advertise that limit.

If we required that if a peer has a limit, it must advertise it and enforce it, then closing the connection makes sense to me. Given it's really easy to advertise it and it's within encryption, I don't see any reason not to make that change, but it's a slightly larger change than the other cases, where we're changing obviously avoidable errors to connection errors.
Happy to spin off another issue. See Section 5.1.1 for usage. Is the intent here "unlimited, but not really and I may reject at any time without sharing my limit". How is a peer that broke the rule expected to recover from such an error?
How about "an endpoint encountering a header list larger than the value advertised using SETTINGSMAXHEADERLISTSIZE parameter MUST close the connection with a connection error." I do not think we should mandate the use of SETTINGSMAXHEADERLISTSIZE when imposing a limit on the header list size. This is because the maximum can be different between requests. For a proxy, the maximum size is actually unknown, because each origin would have different maximums. PS. Though such a change would mandate the sender to respect SETTINGSMAXHEADERLISTSIZE (it's not required now).
Let me correct my self. This is wrong. By not forbidding responding with a connection error, we have been effectively mandating the sender to respect the settings parameter. Therefore, I think we can clarify as an editorial change that a client MUST adhere the settings parameter, and then exceeding a limit becomes a protocol violation, which should be treated as a connection error. PS. The text covering this is tentatively pushed to . PTAL.
Your text SGTM. Since HTTP/3 is not yet at a 'higher bar', it doesn't matter too much as long as Mike agrees as well.
From an implementation point of view, being able to classify an error as either a connection error or a stream error would simplify error reporting since we'd be able to classify an error as either a connection error or a stream error without having to include extra information with the error. As an example, at the moment, when returning a error from a function, I have to include whether the is a stream error or a connection error since it can be both.

If every error could be classified as either a connection error or a stream error, I wouldn't have to include this extra information since a error would always be a connection error.
NAME in keeping with HTTP/2, an endpoint can always decide to treat a stream error as a connection error. However, you're correct that some (and after the associated PR, most) errors will always be connection errors, and your implementation could choose to always treat the others as stream errors. Just make sure there's no issue if someone else decides to treat it as a connection error.
Fixed in , which should have closed this.
the very end of Section 4.2.3 of quic-http says: PRIORITY frames received by a client MUST be treated as a stream error of type HTTPUNEXPECTEDFRAME. Elsewhere, this kind of thing is a connection error. Making this a stream error seems problematic; if otherwise valid, if this goes out on the control stream a stream error may bring everything down anyway? Here is the mailing list thread: URL I believe the consensus is to make it a conn error; PR to follow. the very end of Section 4.2.3 of quic-http says: PRIORITY frames received by a client MUST be treated as a stream error of type HTTPUNEXPECTEDFRAME. Elsewhere, this kind of thing is a connection error. Making this a stream error seems problematic; if otherwise valid, if this goes out on the control stream a stream error may bring everything down anyway? Should this be a connection error, or am I missing something?