Original text:
Servers MAY serve HTTP/3 on any UDP port, since an alternative always includes an explicit port. <del> 3.2.1. This document defines the "quic" parameter for Alt-Svc, which MAY be used to provide version-negotiation hints to HTTP/3 clients.  QUIC versions are four-byte sequences with no additional constraints on format.  Leading zeros SHOULD be omitted for brevity. Syntax of the "quic" parameter value: Where multiple versions are listed, the order of the values reflects the server's preference (with the first value being the most preferred version).  Reserved versions MAY be listed, but unreserved versions which are not supported by the alternative SHOULD NOT be present in the list.  Origins MAY omit supported versions for any reason. Clients MUST ignore any included versions which they do not support. The "quic" parameter MUST NOT occur more than once; clients SHOULD process only the first occurrence. For example, suppose a server supported both version 0x00000001 and the version rendered in ASCII as "Q034".  If it also opted to include the reserved version (from Section 15 of QUIC-TRANSPORT) 0x1abadaba, it could specify the following header field: A client acting on this header field would drop the reserved version (not supported), then attempt to connect to the alternative using the first version in the list which it does support, if any. </del> 3.3. HTTP/3 relies on QUIC as the underlying transport.  The QUIC version 11.2. <del> This document creates a new registration for version-negotiation hints in the "Hypertext Transfer Protocol (HTTP) Alt-Svc Parameter" registry established in RFC7838. "quic" This document, 11.3. </del> This document establishes a registry for HTTP/3 frame type codes. The "HTTP/3 Frame Type" registry governs a 62-bit space.  This space is split into three spaces that are governed by different policies. values of N (that is, "0x21", "0x40", ..., through "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. <del> 11.4. </del>  This document establishes a registry for HTTP/3 settings.  The "HTTP/3 Settings" registry governs a 62-bit space.  This space is values of N (that is, "0x21", "0x40", ..., through "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. <del> 11.5. </del>  This document establishes a registry for HTTP/3 error codes.  The "HTTP/3 Error Code" registry manages a 62-bit space.  The "HTTP/3 The entries in the following table are registered by this document. <del> 11.6. </del>  This document establishes a registry for HTTP/3 unidirectional stream types.  The "HTTP/3 Stream Type" registry governs a 62-bit space.

Reviewer comments:
As discussed in Cupertino, we're punting the hard part of this issue to future versions, but we can remove the version hint until then.
According to URL, the Alt-Svc parameter value can be unquoted: This means that this can be written: instead of only: The current text in URL forbids the unquoted variant which is an additional constraint on the RFC 7838 grammar. Should unquoted parameter values also be permitted? Note that this does not change the situation when multiple versions are supported since an unquoted "token" type is not allowed to contain commas. See also the discussion in .
RFC 7838 allows unquoted strings, but there's nothing preventing new specifications of Alt-Svc parameters from being more restrictive. I'm not sure the added flexibility of allowing unquoted versions buys us much here, and it comes at an implementation cost.
If alt-svc can be specified in configuration files, it is likely to result in interop issues if unquoted is not permitted.
I support allowing unquoted token for alt-svc quic parameter. quic=1 and quic="1" are semantically the same, and there is no reason to disallow unquoted token. Moreover, requiring quoted-string means that we cannot use generic alt-svc parser because such parser can parse quic=1 without an error. You need to write your own parser to detect that the DQUOTE is really there. If you think that detecting it is not necessary, then requiring quoted-string is not necessary in the first place.
People and implementers will be surprised (and do wrong) if the rules and constraints of RFC7838 aren't kept.
To highlight my earlier point, on slack the following was posted The issue appears to not be the unquoted ma=3600, but it does suggest we will see unquoted strings in the wild, and URL is said to also use unquoted ma=3600.
But that's the ma= field, not the quic= field, right? (This issue is about the quic= field, I think)
As I said elsewhere, the current text in draft-23 stems from a Structured Headers issue related to wanting to advertise multiple versions of QUIC. URL Alt-Svc isn't a structured one but if it were (e.g. if someone wanted to write a generic Structured Header parser) then there was a danger that the rules preventing dictionary key repetition would have prevented an endpoint sending multiple parameters e.g. . To mitigate the risk, the quic parameter was changed to a DQUOTED comma-separated list as part of URL This issue addresses the correctness within the Alt-Svc spec but does it reopen the can related to Structured Headers?
I think that the problem here is independent from whether structured headers should be applied or not. - Structured header issue: duplicate keys. - Invalid grammar according to RFC 7838 since "token" does not include commas. - valid grammar according to both RFC 7838 and the QUIC description. However, if only a single version has to be advertised, then the quoting is not necessary: - valid grammar according to both RFC 7838 and the QUIC description. - valid grammar according to both RFC 7838, but QUIC currently forbids it. In I proposed to fix the grammar (editorial issue). However, at the same time I could also make the grammar match RFC 7838 (the last bullet point above). NAME I would mind not making the semantics more restrictive (e.g. restricting the values of the QUIC parameter to hexadecimal only), but restricting the parser grammar would impose extra restrictions on those who have to generate the header. It is conceivable that implementations will continue accepting the RFC 7838 grammar, and end up accepting while others would reject it and accept only. By making sure that the grammars align, I hope that this becomes a non-issue. So far NAME NAME and NAME seems to support this proposal and NAME is not sure. Can this be considered consensus? :smiley:
. This allows the server to indicate which versions of quic-transport it prefers. However, there is no guidance as to what to do in the absence of such hints. If a client receives (without any hints), is it expected to start with QUIC version 1, or with the client's preferred QUIC version? If a client receives , is it expected to start with (draft-ietf-quic-transport-23)? We may want to provide guidance in draft-quic-http to ensure everyone's on the same page.
I happy to be proven wrong but it seems like noone uses this parameter as specified and it raises all sorts of questions. I'm leaning towards killing it off. NB: I am aware that Google have long used this parameter but I'm not convinced it is interoperable and deployable.
The Version Hints presumably exist to avoid one roundtrip for the . Thus without hints, a client could probably decide to use any version it supports (1 or whatever latest version it desires to use). FWIW Google uses alt-svc, but I do not remember seeing the version hint parameters. For example:
in this case the "v" parameter is comparable to the "quic" parameter
Edit: nevermind, I need to read better. Removing the parameter was previously suggested in , but that did not seem to proceed.
NAME I also lean towards killing it off. However, that would prevent us from doing something like: h3=":443", quic="1,2" At some future date when we have QUICv1 and QUICv2 and we want to support HTTP/3 over either of them. Does that seem problematic? Of course, if the alpn continues to imply the transport version and HTTP+QUICv2 == HTTP/4 then we wouldn't ever need to advertise this.
That's a compelling argument, I'm just concerned that we aren't seeing this used much today and so when the time comes that you'll need it, it won't work as we all hoped. Perhaps we could defer the quic parameter until v2 - similar to other VN related issues.
I think the question is if we expect changes in the application protocol (i.e. HTTP/3) when we define QUIC v2. If we suspect that H3 would remain as-is for QUIC v2 (I'd assume that would be the case if v2 is going to be greasing or multi-path), then it would be reasonable to define the transport version identifier of the Alt-Svc header in H3. If we are uncertain, I do agree that it might be a good idea to defer it.
We also have a hard time testing this today - there is no standard legal valid combination of "h3-N" and quic versions that would allow a client to select one QUIC version over another. Perhaps this was a motivator for URL
It's fine to omit this parameter. As NAME notes, if the client supports multiple versions of QUIC, this helps avoid the need to do Version Negotiation. However, it's only an optimization -- in the absence of this information, the client does any version of QUIC it believes to be compatible with the ALPN token(s) it is offering. If the server needs to do VN, it will. (Details TBD, unfortunately.) Is this critical to HTTP/3? No, and it could reasonably be extricated to a separate document until such time that there are multiple QUIC versions. Most stacks currently support only one version at a time, so this doesn't serve much purpose. If HTTP/3 doesn't require breaking changes to keep up with QUICvN, this probably serves a purpose on the day there are several. Personal opinion: If anyone thinks this is half-baked, let's set it aside until we need it, with the rest of VN. If we're fairly confident this is what we want, however, it saves us the trouble of defining another separate RFC later.
I'm worried that relying on clients to "do the right thing" might cause serious performance issues down the road. I'd prefer to either have explicit guidance, or remove this mechanism until we understand it better as NAME suggests.
It was designed at a stage where QUIC had a fully-defined Version Negotiation mechanism. The client could offer any version -- in fact, was encouraged to offer a grease version -- on the first flight, and would learn the server's list of versions in response. But if you knew that list up front, either via Alt-Svc or because you've connected before, you could save a round-trip by selecting something that was on the list. And if your information was wrong, or stale... oh well, you get a VN packet and learn the correct list. Now, we don't have such a mechanism and receipt of a VN packet is fatal. There are two ways to look at this: There is only one version, so we can define this mechanism once it can be paired with a version negotiation mechanism. Getting the server's version wrong is fatal, and therefore this mechanism is essential.
Here's what 5.4.4 says However, RFC 8439 says: This is a little confusing, but I think the correct way to read this is that the ChaCha function takes the nonce as a 96-bit opaque quantity, and the fact that it's little-endian is an internal detail irrelevant to our purposes, so we should just replace the second sentence with "The remaining 12 bytes are used as the 96-bit ChaCha nonce". This is reinforced by the fact that the test vectors have the nonce as a byte block. The situation with the counter is more complicated because we are told it is both a counter and 32-bits (which might make you think it's an integer parameter), but it is also treated as a little-endian integer, which makes one think it's a bitstring. And then the test vectors treat it as a value, rather than as a bitstring. If you look at code it typically thinks of this as an integer: See, for instance: URL So, I think the right answer here is to think of ChaCha as having the following API: Note that because the value on the wire is in big-endian format, this would invert the nonce, but I think it's the right answer anyway. Otherwise, you're having to pass in the counter in the wrong format on big-endian platforms.
As a completely general note, I don't think it is right to change endianness of crypto wire formats. AES-GCM has a completely backwards neither little nor big endian encoding (byte and bit swapped so no platform wins) this remains so on the wire. Especially for HW processing this is significant. But little endian is also more performant on nearly all relevant platforms today so there is no need to go over board forcing big endian if it can be avoided without insulting RFC's.
Yeah, this should simplify that text some.
I like the proposed change, the text had somewhat confused me when implementing this in a previous life.
I don't think that the reinterpretation of the little-endian thing is safe, as per NAME comment. The takes a byte buffer as input rather than a . That is to allow for different block counter sizes. I'll make the editorial change, but leave the suggestion there alone.
I have a question out to the editor of the PKCS spec. It appears like there are no solid rules in the spec to support any particular position here. I'm going with my best guess at WWDJBD here, but I'm happy to make a change if there is a strong case made for something else.
NAME NAME can we flip this to please? I don't think that we need to change the substance here, but I want to confirm the little-endian/big-endian choice here. I hope to have more information to share on the question soon, but that might not be definitive. We might just have to make a call ourselves. Absent better information, I'm going to suggest that we continue with little-endian, but I this is far from an obvious conclusion.
The API I'm using for ChaCha20 takes a const uint8_t nonce[12], and I currently pass in a pointer (offset by 4 bytes) to the sample as the nonce, without doing any endianness conversions. I'm in favor of clarifying the language for this input. (Given that this has the design label instead of the editorial label, my design opinion is to keep with the simple thing of passing the bytes directly from the sample to the nonce input of ChaCha20 and not do any endianness conversions. I'm assuming that other crypto libraries have similar APIs though.)
The API I have takes . PKCS takes pointers just like the API NAME refers to (but it fails to specify the endianness, which is a critical oversight, compounded by the fact that the size of the counter can vary). I suspect that - as NAME says - the right idea is to note that ChaCha20 will interpret the nonce as three little-endian integers and that the counter might be expressed as a byte sequence that is then (probably) interpreted as a little-endian integer.
I understand and appreciate this being marked as “design”, though I consider the text that landed in master as editorial, as it (in my view) ended as adding practical advice while retaining the definition we have had.
Yes, but as a design issue, we want to confirm that "no action" is the correct outcome. It's cheap enough to do so.

Revised text:
Servers MAY serve HTTP/3 on any UDP port, since an alternative always includes an explicit port.  3.3. HTTP/3 relies on QUIC as the underlying transport.  The QUIC version 11.2.  This document establishes a registry for HTTP/3 frame type codes. The "HTTP/3 Frame Type" registry governs a 62-bit space.  This space is split into three spaces that are governed by different policies. values of N (that is, "0x21", "0x40", ..., through "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA.  <ins> 11.3. </ins> This document establishes a registry for HTTP/3 settings.  The "HTTP/3 Settings" registry governs a 62-bit space.  This space is values of N (that is, "0x21", "0x40", ..., through "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA.  <ins> 11.4. </ins> This document establishes a registry for HTTP/3 error codes.  The "HTTP/3 Error Code" registry manages a 62-bit space.  The "HTTP/3 The entries in the following table are registered by this document.  <ins> 11.5. </ins> This document establishes a registry for HTTP/3 unidirectional stream types.  The "HTTP/3 Stream Type" registry governs a 62-bit space.