Change:
Simple. It appears as though I missed this when NAME added this transport parameter. We shouldn't make more exceptions for 0-RTT.
This is a bigger design change than it might look like from the diff. Our design principle was to only remember things for 0-RTT that are actually needed to make 0-RTT work. This means that we need the flow control limits as well as the stream number limits, because obviously the client needs to be able to send application data in 0-RTT. This saves state on the client side (because the client only needs to remember those 6 parameters) as well as in the session ticket (because that’s how the server stores that state). A reasonable implementation strategy on the server is to reject 0-RTT if those parameters changed / were reduced, so keeping the number of things to remember small increases the probability that 0-RTT is not rejected.
"needed to make 0-RTT work" has slightly fuzzy boundaries, though. A more concrete rendering of the principle is that the client needs to remember any limit which it might exceed prior to receiving the actual limit in the ServerHello. The possible solutions for any given TP, then, are to structurally ensure that the client can't exceed it in 0-RTT or to remember it.
From comment URL How is the TP to be remembered when it is to be ignored when 0 length CID is received?
After looking back at the notes(linked on the issue), I see we had fairly strong agreement on this at the time, so I'm willing to let that stand, even if it's not what I think is the optimal choice.
This value is not remembered for 0-RTT. A client therefore cannot send NCID frames in 0-RTT without risking to violate the server’s limit.
The alternative would be to add it to the list of things to remember, but yes, we should fix it.
NAME That would mean that the server needs to remember / save in the session ticket, and can’t reduce in the resumed connection. My understand was that we only remember those values that are absolutely necessary to make 0-RTT make sense, i.e. flow control and stream number limits.
Discussed in ZRH. NAME to write up a PR for his preferred option.
Post-discussion and having re-read, I believe the current text covers this for NEWCONNECTIONID: The client has already issued one CID to the server during the handshake, which might be zero-length Sending NEWCONNECTIONID is forbidden if you are using zero-length CIDs; receipt of one is a protocol violation The default and minimum value of applies until the server's value is received, which is two if the client is using non-zero-length CIDs Exceeding the limit is a protocol violation So the client can send no more than one NEWCONNECTIONID frame in 0-RTT, or it's a protocol violation. If it sends exactly one, that never exceeds the server's limit, provided that it has a non-zero-length Source Connection ID. It also covers it for RETIRECONNECTIONID: The client has exactly one CID for the server during 0-RTT It is a protocol violation for RETIRECONNECTIONID to retire the CID used by the containing packet
Over supper, NAME wanted to know why a client would include a new connection ID in its 0-RTT packets. The answer is that the client's handshake CID has no associated SRT. If the client wants the ability to send stateless resets, it might very well put NCID(N=1, RPT=1) in its 0-RTT flight. The server will retire the handshake connection ID in 0.5-RTT and begin using the CID with an associated token.
Discussed in ZRH. Proposed resolution is written up in .
The meeting notes record that there was a 12 to 1 vote for saving the value instead of using the default of 2. URL I believe I was convinced by the argument that a server could just always use the default and never change it, so it doesn't really matter for servers.
I agree with NAME Although a client could decide to not remember the activeconnectionidlimit (and would then not not be able to send more than one CID in 0-RTT packets), the server needs to store this value in order to decide whether to accept or to reject 0-RTT. This seems like a bit of a hassle for something that doesn't provide any real-world benefits.Besides the motivation of minimizing exceptions in 0-RTT, I'm not sure why we're making this change? Remembering more TPs makes server upgrades and config changes potentially more disruptive, as has been discussed, and there's no critical use case for the client to send NEWCONNECTION_ID in 0-RTT.

Discussion:
A client need not store a transport parameter it cannot process. A client MUST NOT use remembered values for the following parameters: <del> original_connection_id, preferred_address, stateless_reset_token, ack_delay_exponent and active_connection_id_limit.  The client MUST use the server's new values in the handshake instead, and absent new values from the server, the default value. </del> <ins> original_connection_id, preferred_address, stateless_reset_token, and ack_delay_exponent.  The client MUST use the server's new values in the handshake instead, and absent new values from the server, the default value. </ins> A client that attempts to send 0-RTT data MUST remember all other transport parameters used by the server.  The server can remember

initial_max_streams_uni <ins> active_connection_id_limit </ins> Omitting or setting a zero value for certain transport parameters can result in 0-RTT data being enabled, but not usable.  The applicable subset of transport parameters that permit sending of application