Change:
packets, such as timing and size, from being used to correlate activity. <ins> An endpoint SHOULD NOT initiate migration with a peer that has requested a zero-length connection ID, because traffic over the new path might be trivially linkable to traffic over the old one.  If the server is able to route packets with a zero-length connection ID to the right connection, it means that the server is using other information to demultiplex packets.  For example, a server might provide a unique address to every client, for instance using HTTP alternative services ALTSVC.  Information that might allow correct routing of packets across multiple network paths will also allow activity on those paths to be linked by entities other than the peer. </ins> Unintentional changes in path without a change in connection ID are possible.  For example, after a period of network inactivity, NAT rebinding might cause packets to be sent on a new path when the

Discussion:
Not making a design/editorial call here. There is new normative language, so maybe it is design. But this is really just documenting an emergent property of the existing system. There are no concrete changes other than a stronger recommendation against migration in cases where it either doesn't work or would not provide the privacy properties we have attempted to guarantee.
I think we already knew this, but it's also not that relevant to most migration scenarios when the client is migrating and has a 0-len CID, so I think it's fine.
NAME the issue is that, while the server might be confident it will work (and therefore not set the TP), the only way it works is by being highly linkable. If we think linkability is a bad thing, advising clients not to do it isn't unreasonable. Of course, servers have other ways of making a connection linkable by observers if they choose to do so, and clients can't detect all of them. I'm not sure this warrants normative force; I'd simply mention that clients who intend to minimize linkability might want to consider that they're definitely linkable in this situation and could choose to avoid it.
We don't prohibit the use of a zero-length connection ID in the preferredaddress transport parameter. So a server can use a connection ID during connection establishment, then remove privacy protections by moving to a unique address (see ). Of course, this is largely moot, as the privacy protection offered through the use of connection IDs toward a unique address is nil. In either case, we should clarify whether preferredaddress is exactly like NEWCONNECTIONID, or whether it has its own rules. Right now, it looks like it has its own rules and that is likely bad.
Zero-length connection IDs don't have a stateless reset token associated with them, but the preferred_address TP requires you to set a token. That's an awkward corner case.
That is just one of the strange things, yeah. We should clarify that.
So I see a number of ways forward here: Do nothing. Leave this ambiguous and potentially special. Make the fields in preferredaddress exactly equivalent to a NEWCONNECTIONID with a sequence number of 1. But allow the connection ID to be zero-length. A zero-length connection ID provides a new stateless reset token that is bound to the new address.

(This is a weird option that would go against previous decisions to eliminate special handling for this connection ID, but I include it for the sake of completeness.) As 2, except that the new stateless reset token has connection-wide scope such that either of the provided tokens can be used. This is more consistent with established principles. Prohibit the use of zero-length connection IDs in preferredaddress. That is, you can't use preferredaddress without a connection ID. That is, preferredaddress effectively is a new server address plus a NEWCONNECTIONID frame. Something else. From my perspective, I rank these as 4 > 3 >> 1 > 2. But that is largely based on my bias against zero-length connection IDs (as much as it seems like that might be good for privacy, I think that privacy is better served by the use of connection IDs). If people intend to use preferred_address to migrate to a connection-specific address, then I'm OK with 3; we already have to cover the privacy hole that arises from that.
My preference goes to option 4 too. I do not think servers would use both 0-byte CID and preferredaddress TP at the same time. The only case a server using 0-byte CID can also use preferredaddress is: when the server is never accepting more than one connection at a time, or when the server knows that the client's address tuple does not change when the client migrates to a new address IMO that's a niche. And when these cases can be met, I do not see why the client cannot know the preferred address of the server beforehand.
I forgot to add: There is (maybe) a case for using a connection ID during setup and a zero-length connection ID after migrating to a preferred address. That isn't entirely crazy, but I personally would be comfortable losing that option. But I don't operate a server, so I want to give those who do a chance to let me know that this is preemptive.
NAME My personal take would be that people would not do that. When a client migrates to the preferred address, there's fair chance that the client's address tuple will change. That means that the server should be capable of receiving short header packets with 0-byte CID from any address, and determine that the packet belongs to the connection that is migrating to the preferred address.

That's possible theoretically, but in practice ... I agree that a server might want to switch to zero-byte CID after migration to SPA completes. But to do that, we need a NEWCONNECTIONID that can carry a zero-byte CID, which is forbidden at the moment. I do not think we'd want to change the spec now to allow that.
That's an excellent point, and a good reason not to allow changing to zero-length connection IDs in combination with preferred_address. The nasty part of that is that in most cases that design would work because clients won't use the "new" connection ID until after the handshake is complete. Of course, it would fail spectacularly if a client did decide to switch earlier - and the client might attract the blame, where it is clearly the fault of the server.
I'll note that prohibiting a 0 length CID doesn't actually ensure the server's IP isn't unique, though it does remove an incentive to make it unique. I'd like to leave the option to switch to a zero-length CID later in the connection, and I think I'd be fine with 4 if we allowed that. An easy example is a large upload. I mostly don't care about the CID, but if I'm uploading a 10GB file, maybe saving some bytes matters. Also, if you're constantly filling the pipe, NAT rebinds are extremely unlikely. Another example is an environment like a datacenter where there are no NATs and routes are very stable, unless a peer intentionally changes it, so the 5-tuple is sufficient. In that case, the ideal operating condition is to typically use a 0 byte CID and switch to a non-0 length anytime a peer changes IP or port. Changing port has some clear benefits in some cases, so it's in no way a threoretical use case. NAME may have thoughts on this range of use case as well.
In our implementation, we plan to do all routing based purely on the CID. IMO, the couple of byte overhead in a 1500 MTU (at least; in datacenter) packet isn't going to make much difference, so it's just simpler to have a common CID routing scheme. That being said, I personally am not against allowing for others to do something different.

I've never understood why we make any restrictions on changing between 0-length and non-0-length CIDs at all. IMO, the complexity is that it can change length at all, not that it's zero or not.
NAME we already prohibit changing from non-zero-length to zero-length using NEWCONNECTIONID. I don't want to relitigate that. I want to concentrate on this specific issue.
If we're not going to re-litigate that, then I'd suggest we continue allowing a 0-length CID for the preferred address case.
NAME While I would not argue strongly against continue allowing that, I would appreciate it if you could clarify why allowing a zero-byte CID would be useful. As pointed out in URL, when you provide a zero-byte CID in SPA, you need to be prepared for receiving a short header packet using zero-length CID from any IP address, and be capable of associating that to an existing connection. This is because the client (or the network) might change the client's address tuple when it sends packets to the preferred address. I would anticipate that you wouldn't want to do that in your file upload case (or in any deployment that might accept multiple connections concurrently).
NAME If I know 5-tuples are stable, then using a zero-length CID is always fine, just like it's typically fine in the server to client direction. But in that case, hopefully I can avoid needing to use SPA, making the decision on this issue moot. After thinking about this more, we're probably better off with option 4 for the sake of consistency and if we want to allow 0-length CIDs in more cases, I can write an extension for how that would work, since I don't think it's only a matter of relaxing some constraints.
Thanks all. I think that we reached the same conclusion in the end, via different paths. The proposed fix here is firmly design chairs. A bugfix only, but still worth careful review.
Apologies for getting to this late, but I'm not sure I agree that we should disallow this. Here's a use-case that I think makes sense: the client wants to upload a very large file to the server over HTTP/3 and it has a small MTU, making it particularly sensitive to per-packet overheads.

Let's also assume that we are in the future and the server supports IPv6 and has its own /64 (shocking!). In this scenario, a good way to reduce per-packet overhead is to operate the server on a given address, and then switch each client to their own unique server IP using preferred address, and then use zero-length CIDs. I've always found this use-case a good use of preferred address, and I would rather we didn't ban it without a good reason (and making the design cleaner doesn't necessarily count as a good reason at this stage in the process).
That is an example we discussed. As Kazuho noted, that doesn't work as we have already agreed that any connection ID (in this case, a zero-length one) can be used prior to handshake completion. That's why we ended up on 4. As Ian noted, this isn't ideal, but this is an area that is ripe for extensions that might allow this sort of thing.
I don't understand what you meant by the following: Can you clarify? I was under the impression that the client switches to the preferred address after the handshake is done.
Yes, you can't migrate (act on the address information) before the handshake is confirmed. However, the connection ID is not special; it can be treated just like any other connection ID you learn, so you can act on the connection ID information before you confirm the handshake. So that means that a server that opts to include a zero-length connection ID in the preferred_address might receive a packet with the zero-length connection ID at the old address. That might not work out.
What's the point of including a connection ID (and stateless reset token) in the transport parameter if that CID isn't tied to the preferred address in any way? At that point might as well remove that CID entirely and rely on NEWCONNECTIONID frames. My understanding was that the reason for there being a CID in the TP was specifically to make that CID special. Would it make sense to just say that this CID MUST NOT be used when sending to the handshake server IP?
the reason for having a connection ID in the transport parameter is only so that the client has a connection ID to use for the new path
NAME I agree with your intuition, but I think we discussed this in Zurich and ended up concluding the preferredaddress CIDs weren't special.

This was in issue and also came up in (which I realize hasn't gone out for a consensus call yet, that PR seems stalled?). In the upload example, the server needs to know that the client is going to send a lot of data, which it might know via SNI, or it might not. I tend to think the more annoying restriction is that you can't change from a non-0 length CID to a 0-length one and vice versa. By supplying a 0-length CID later in the connection along with other CIDs, the client could choose whether it wanted to use a 0-length CID at any time. Thinking out loud, an easier solution may be a TP like 'acceptemptyconnectionid' that indicates at anytime, the peer can switch to a 0-length CID if it wants. It could either think the 5-tuple is stable or its happy re-establishing the path with a non 0-length CID after a NAT rebind. In this world, the Connection ID is more of a path re-establishment token.
Thanks for the details NAME and NAME I get a sense I might be trying to re-litigate past consensus without providing new information, so I'll back down. I do think that the ghost of hypothetical linkability has caused us to make some very odd design choices, but this isn't new to this issue/PR. In the end, this is the kind of feature that can be enabled by extensions so I can live with us further restricting the base spec for consistency.
One way in which a server might use preferred_address is to enable routing based on the server address alone. Just as a client might benefit from a zero-length connection ID by selecting a unique address from which to initiate a connection (i.e., an ephemeral source port), this enables the server to pick an address that is unique to the connection. Such a server can then establish a connection by routing based on the source tuple, then move to a preferred address that is unique to the connection. This assumes that clients aren't using connection IDs to multiplex multiple connections to the same server, or that they only open one connection at a time, or that servers are willing to do trial decryption during handshakes (that last one being unlikely. because in the general case it is more than just trial decryption).

As a result, the server does not have to request that the client not migrate. The server can use this unique address at its end to identify which connection packets belong to. That's all great, but it creates linkability for the client. When it migrates, the destination address is unique to that connection, for at least as long as that connection is live (which includes the idle timeout, which we have to assume is known to an attacker). It also potentially creates address exhaustion problems at the server as the server has to keep address allocations for a fairly long time to allow for idle connections to time out. Stateless resets are possible, but challenging, because the server has to rely on state in order to generate one. Stateless resets can't be static unless a port is only ever used exactly once (which seems ludicrous). I might conclude here that a zero-length connection ID for a server is just a bad idea, as the server address is stable across migrations and links flows on different paths. There is some uncertainty about linkability when it comes to port reuse, but this does undermine guarantees that clients might assume they have. I see two choices: Prohibit (active) migration when there is a zero-length connection ID at the server end. This would be on the basis that there is a privacy leak that is not obvious. Acknowledge that this happens and leave this to client discretion.
A server that wants to defeat linkability always can. Using , a server could easily enough issue each client its own IPv6 address or, even with IPv4, a unique ephemeral port. Even without it, a server could issue trivially linkable CIDs, disclose its CID key, etc. So the goal is to reduce the chances that this happens accidentally, not to prevent it entirely. We already decided not to prohibit active migration in the presence of zero-length CIDs, IIRC. Given that, I think this is just a textual warning to be cautious in this circumstance.
This is a maybe-design issue with an editorial-shaped proposed resolution. I think we'll start to see a lot more of these. I think we should run the design issue process still, but I leave that to chair discretion.
NAME ^
As I recall and unless something changed recently, active migration is not permitted for 0 length CID, but it is accepted that a NAT migrates outside the peers control.

I read this as a clarification of existing protocol design. I'd like to get eyes on it to make sure there is sufficient opportunity for discussion. Marking as design.
Transport section 9.5 says "An endpoint MUST use a new connection ID if it initiates connection migration as described in Section 9.2 or probes a new network path as described in Section 9.1. ". Section 19.15 (NEWCONNECTIONID) says: "An endpoint MUST NOT send this frame if it currently requires that its peer send packets with a zero-length Destination Connection ID. " I take this means active migration cannot happen with 0-length ID. BTW: in a few places "zero length" used over the more common "zero-length".
I really think we shouldn't disallow connection migration when the server uses zero-length CIDs. As stated above, linkability can happen for a variety a reasons, and we should leave it up to the client to decide whether it wants its bytes to go through or not. Perhaps an editorial paragraph stating this in the migration section or security considerations would do the job.
Thanks for incorporating my suggestions!Latest changes look good!