The 1-RTT rule strict servers enforce
RFC 9001 §4.1.1 says a client must not send 1-RTT data before the handshake is confirmed on its side. Some servers check.
One of the first interop bugs we hit looked like random connection drops against one provider and none against another. The cause was ordering.
The rule
RFC 9001 §4.1.1: a client must not send 1-RTT application data until it has sent its own Handshake Finished. Lenient servers buffer early packets and sort it out; strict servers drop them — and the request silently never arrives.
The fix
// Gate application data on our own Finished
if (!conn.handshake_finished_sent) {
conn.pending_app_frames.push(frame);
return;
}
sendOneRtt(frame);The wire diagram on the home page shows the order: Handshake Finished from the client comes before the first SETTINGS + HEADERS. Coalescing them into the same UDP datagram is fine — the order inside it is what counts.