Skip to content

Version Negotiation Handshake

Protocol step / connect-time agreement — instantiates Round-Trip Code Alignment

Before any real content is exchanged, the two ends advertise which scheme versions they support and settle on a common one, so neither has to guess or convert later.

A version mismatch can be prevented instead of repaired, and that is what a Version Negotiation Handshake does. At the very start of a session — before a single byte of real content flows — each party advertises the scheme versions it can speak; they select the best one both support and bind the channel to it for the exchange. Its defining move is that agreement happens once, up front: the round trip then runs under a scheme both ends are known to share, rather than under one side's hopeful guess about the other. This is the mirror image of a Migration Adapter, which converts encoded content only after a mismatch has already occurred; the handshake's whole point is that the mismatch never occurs.

Example

A client opens a connection to a server. In the opening exchange — before any application data — the client sends the list of protocol versions it supports; the server picks the highest it also supports and replies with that choice, and only then does real traffic begin. This is exactly the shape of the TLS handshake, where the client advertises supported versions and the server selects one. If the client offers v1.2 and v1.3 and the server tops out at v1.3, they proceed on v1.3; a server that only speaks v1.2 pulls the session down to the common floor, and if there is no overlap at all the connection fails fast rather than limping ahead on a guess. Because the negotiated choice is bound into the handshake, a meddler on the wire cannot quietly force both ends down to a weaker version they would not have chosen.[1]

How it works

  • Advertise supported versions. Each side sends the set of scheme versions (and optionally capabilities) it can speak, opening the session with a declaration rather than an assumption.
  • Select against a compatibility rule. A selection rule picks the common maximum — or a policy-preferred version — from what both offered, consulting which versions count as interoperable without itself defining that table.
  • Pin the channel. The chosen version is bound for the rest of the session, fixing what each side is licensed to send and to interpret.
  • Fail closed on no overlap. If the parties share no version, the handshake refuses rather than proceeding on an unsupported one.

Tuning parameters

  • selection rule — highest-common vs. client-preferred vs. a server-mandated floor. Highest-common maximizes capability; a mandated floor enforces policy at the cost of turning some peers away.
  • no-overlap behavior — fail-closed vs. fall back to a baseline version. Fail-closed is safer; a permissive fallback keeps more peers connected but can settle on an old, lossy scheme nobody intended.
  • capability granularity — whole-version vs. per-feature negotiation. Finer negotiation is more flexible but multiplies the state space and the test matrix.
  • downgrade protection — whether the negotiated choice is integrity-bound so it can't be tampered down to a weaker version. Adds safety; adds handshake cost.
  • re-negotiation — agree once at connect vs. allow mid-session renegotiation. Mid-session flexibility buys adaptability at the price of a simpler, more predictable session.

When it helps, and when it misleads

Its strength is that it removes guesswork and post-hoc conversion by making the shared scheme explicit before content flows, and it lets a heterogeneous fleet of mixed versions coexist gracefully instead of failing at the first mismatch.

Its failure modes start with the N×M compatibility explosion: every supported-version pairing is a distinct path that must be tested, and the untested corner is where it breaks. A too-permissive fallback can quietly settle on an old version nobody wanted, and a negotiation that isn't integrity-protected invites downgrade attacks. The subtle classic misuse is treating "the handshake succeeded" as proof that the two ends agree on meaning, when all they agreed on is a version number whose interpretation may have drifted between them. The discipline that keeps it honest is to pin fail-closed by default, integrity-bind the choice, and back the negotiation with a real compatibility matrix and round-trip tests for each supported pairing.

How it implements the components

  • shared_scheme_contract — its output is exactly this: a single scheme version both ends have agreed to speak for the session.
  • channel_or_store_context — it operates at the channel/connection level, establishing the exchange's shared context before any content is sent.
  • interpretation_boundary — by fixing the version up front, it fixes what each side is licensed to assume and interpret — which fields and semantics are in play, and which are off the table.

It does not implement the declarative table of which version pairs interoperate (version_compatibility_rule) — that is the Compatibility Matrix, which it consumes — nor the actual conversion of mismatched content (encoded_form, decode_failure_handling), which is the Migration Adapter, nor the base encode/decode, which is the Parser/Emitter Pair.

  • Instantiates: Round-Trip Code Alignment — it aligns both ends on one scheme before the round trip begins, so no side has to guess or convert.
  • Consumes: Compatibility Matrix — supplies the rule for which version pairings are compatible, which the handshake selects against.
  • Sibling mechanisms: Migration Adapter · Compatibility Matrix · Schema Registry · Codec Specification · Canonicalization Rule · Decode Error Taxonomy · Checksum or Hash Validation · Round-Trip Property Test · Golden Test Vectors · Lossy Compression Profile · Parser/Emitter Pair

Notes

A successful handshake guarantees agreement on the version label, not on its meaning: if the two ends have drifted in how they implement the same version, negotiation still reports success. The handshake is therefore only as trustworthy as the shared, tested scheme definition sitting behind the version number it settles on.

References

[1] Version-downgrade protection — binding the negotiated choice into the handshake's own integrity check so an on-path attacker cannot force both ends onto a weaker version than they would otherwise have selected — is a real feature of the modern TLS handshake, and the reason downgrade protection appears above as a genuine tuning dial rather than an afterthought.