Skip to content

Upgrading ​

How operators upgrade or downgrade safely — the 8-case upgrade matrix, finalize semantics, and the downgrade pre-check.

Source of truth: the upgrade matrix is frozen design, not implementation status. Every case is a release gate: a red cell blocks the release, it does not get a documentation footnote.

Decision first: which direction am I going? ​

  • Upgrading within the compatible tier (F1, F2, F4, F5, F6) → rolling upgrade, one node at a time, replication protocol takes min(both versions).
  • Upgrading across an incompatible tier (F3) → one-way. The old binary refuses to read the new segment rather than guessing; that refusal is the safety feature.
  • Downgrading (R1, R2) → only after the pre-check below. If any metadata change is irreversible, R2 refuses and tells you which one.

The 8-case matrix ​

#FromToDirectionExpected behaviourDiagnostics requiredBasis
F1segment format_version=1segment format_version=1same versionNormal read/write—baseline
F2segment format_version=1segment format_version=2 (compatible tier)v1 reads v0Must be readable; golden tests lock byte-level behaviour—Kafka downgrade rule (downgrade allowed only with no metadata change)
F3segment format_version=1segment format_version=2 (incompatible tier)v0 reads v1Refuse to start, or refuse that segment; SEGMENT_VERSION_TOO_NEWThe error must carry the file path and the version valueNSQ LoadMetadata parse-failure precedent
F4metadata log MMML v1MMML v2v0 reads v1Same as F3; an unknown record type follows the version ruleSame as F3Kafka MetadataVersion boolean bits
F5client protocol v0broker protocol v1old clientNegotiate down, or reject with UNSUPPORTED_VERSION (0x0004)The error must be actionable (the RocketMQ #504 lesson)—
F6mixed rolling clusterleader v1 / follower v0replication streamReplication protocol takes min(both versions); log a deprecation warningWarning must name both versionsKafka rolling upgrade, one node at a time (Kafka upgrade.md:94)
R1compatible tierv2 → v1rollbackAllowed; run the downgrade pre-check first—RabbitMQ COMPATIBILITY range notation; Kafka upgrade.md:96
R2incompatible tierv2 → v1rollbackRefuse, and name which metadata changes are irreversibleMust list the irreversible changesKIP-848 (after adopting the new protocol you can only downgrade to 3.4.1+); Kafka upgrade.md:294

Reading the two directions that matter most ​

F3 is the interesting one. An incompatible read is not "corrupt the data and hope" — it is a refusal, and the refusal must be actionable: without the file path and the version number, an operator cannot tell which of 64 MiB of segments is the problem. That is why the diagnostics column is a requirement, not a nicety.

R2 is the honest boundary. Not every downgrade is possible, and pretending otherwise is how clusters get bricked. R2 refuses by design and names the irreversible change — the same discipline as the "honest boundaries" section of the threat model.

finalize semantics ​

Placeholder: replication-stream finalize rules are not defined yet; upgrades are two-phase (Kafka rolling-upgrade model).

Downgrade pre-check ​

  • [ ] wire_version has not been bumped
  • [ ] Segment / metadata format_version are within the compatible tier
  • [ ] No leftover quarantine/ directories
  • [ ] No metadata record type introduced after the tier boundary (R2 would have refused at this line)

Without code yet

No binary to upgrade today. The matrix is the release gate: when the upgrade-matrix script lands, these 8 cases run in CI and a red row blocks the release.