RabbitMQ

Upgrading RabbitMQ 3.x to 4.x Without Downtime: Rolling vs. Blue-Green

Scott Sternloff

By Scott Sternloff, Senior Enterprise Architect

LinkedIn · Updated

3.13EOL4.xCURRENTNo DowntimeRolling & Blue-Green Upgrade
Upgrading RabbitMQ is one of those operations that should be straightforward but routinely catches teams off guard. The version path constraints are non-obvious, the Erlang dependency adds another moving part, and the cost of getting it wrong in production is high.
This post covers the two strategies that work — rolling upgrade and blue-green deployment — and the pre-upgrade steps that most teams miss, including feature flag enablement and Erlang version compatibility checks.

Why do RabbitMQ upgrades go wrong?

The most common failure pattern is a team that hasn't upgraded in a year or more, decides they want to jump to the latest version, and skips the intermediate steps the version upgrade path requires.

"A lot of times what companies struggle with, or they forget, is they don't do frequent upgrades. Sometimes it takes a couple years to do an upgrade. And if they try to go from where they are straight to the latest, they get a bunch of unforeseen issues — because what they should have done is upgrade step by step."

Jeff Sogolov, AceMQ Engineer, Lucidya engagement session, May 2025

RabbitMQ has a defined upgrade path. You cannot skip major versions. If you're on 3.12, you must upgrade to 3.13 before you can upgrade to 4.x. Trying to jump directly causes cluster instability and compatibility issues that are difficult to diagnose.

What is the required upgrade path from 3.x to 4.x?

The version upgrade path is documented by Broadcom and must be followed precisely. The key rule: you can only upgrade one major version at a time.
From 3.12 → must go to 3.13 → then to 4.x. You cannot go from 3.12 directly to 4.1. If you're further behind — on 3.10 or 3.11 — you must step through each major version in sequence.
Each step before upgrading also requires enabling all feature flags on the current version before proceeding:
rabbitmqctl enable_feature_flag all
Skipping feature flag enablement before a version jump is a common source of upgrade failures. Always confirm all flags show as enabled before moving to the next version.

What about Erlang compatibility?

Every RabbitMQ version specifies a minimum and maximum supported Erlang version. Upgrading RabbitMQ without upgrading Erlang to the required version first will cause the new RabbitMQ version to fail.
Key Erlang checkpoints for the 3.12 → 3.13 → 4.x path:
  • 3.12 supports Erlang 25.x minimum
  • 3.13 requires Erlang 26 minimum (26.2 recommended)
  • 4.x also requires Erlang 26.2 minimum

"You can upgrade Erlang from 25 to 26.2 directly. Once you're on 26.2, you upgrade RabbitMQ to 3.13 — you already have the right Erlang. Then from 3.13 to 4.1, same Erlang version still applies."

Jeff Sogolov, AceMQ Engineer, Lucidya session, May 2025

Strategy 1: Rolling Upgrade (In-Place)

A rolling upgrade upgrades your existing cluster nodes one at a time, without creating a new cluster. You stop one node, upgrade RabbitMQ (and Erlang if needed), restart it, then move to the next node.
How it works:
  1. Stop node 1 (service only — not the OS)
  2. Upgrade Erlang on node 1 to the required version
  3. Upgrade RabbitMQ on node 1 to the target version
  4. Start the RabbitMQ service on node 1
  5. Confirm node 1 has rejoined the cluster and is healthy
  6. Repeat for nodes 2 and 3
During the rolling upgrade, your cluster runs mixed versions temporarily. This is supported within a single major version but not across major version boundaries. Do rolling upgrades during low-traffic periods — upgrading under heavy load adds risk as quorum replication and message syncing create additional overhead.
Pros: No new infrastructure required, simpler orchestration, uses existing cluster membership. Cons: Brief per-node restarts cause connection disruption; must be done during low traffic.

Strategy 2: Blue-Green Deployment

A blue-green deployment creates a brand-new cluster (green) alongside your existing cluster (blue), migrates traffic to the new cluster using federation, and decommissions the old one once the transition is complete.
How it works:
  1. Provision a new cluster (green) on the target RabbitMQ and Erlang version
  2. Configure a federated queue upstream on the green cluster pointing to the blue cluster
  3. As consumers are moved to the green cluster, federation pulls messages from blue to green automatically
  4. Once all consumers are on green, move producers to green
  5. Once producers are moved, drain any remaining messages from blue using the shovel plugin
  6. Decommission the blue cluster
Key distinction: Use federated queues, not federated exchanges. With federated queues, when a consumer is present on the downstream (green) cluster, messages are pulled from the upstream (blue) cluster and consumed there — they don't persist on both sides.

"Blue-green is zero downtime. You can do it at any time — there's no maintenance mode. The cost is that you have two clusters running at the same time, which some companies can't afford, especially on-prem. But for AWS-based deployments where you can spin up new clusters easily, it makes a lot of sense."

Jeff Sogolov, AceMQ Engineer, Lucidya session, May 2025

Pros: Zero-downtime migration, can be done at any time. Cons: Requires temporary double infrastructure, more configuration steps.

Pre-upgrade checklist

Before starting any RabbitMQ upgrade:
  • Confirm current RabbitMQ version and identify the required upgrade path
  • Check the Erlang compatibility matrix for target and intermediate versions
  • Enable all feature flags on the current version (rabbitmqctl enable_feature_flag all)
  • Back up cluster definitions (topology, users, permissions) via Management API
  • Validate staging environment upgrade end-to-end before touching production
  • Confirm load balancer health check behavior with nodes taken offline
  • Test client reconnect behavior in staging under simulated node restarts
  • Schedule during lowest-traffic window if using rolling upgrade
  • Have rollback plan documented before starting
Multi-version RabbitMQ upgrades — especially the 3.x to 4.x jump — are one of the most common engagement types we handle. If you'd like help scoping the upgrade, designing the migration approach, or having an AceMQ engineer run it during your maintenance window, contact our RabbitMQ support team.

For the wider readiness view before you commit to a window, see the RabbitMQ migration readiness checklist.

What changes in RabbitMQ 4.x that can break a 3.x estate

Most 3.x to 4.x upgrades that go wrong fail on one of a short list of changes. None of them are surprises if you read the 4.0 release notes, but each one is easy to miss in a large estate that grew up on 3.8 and 3.9 conventions.

Classic queue mirroring is gone. Mirrored classic queues (the ha-mode and ha-params policy keys) were deprecated in 3.9 and removed in 4.0. A 4.x node does not mirror classic queues, so any queue that relied on an HA policy for replication becomes a single-node queue the moment the policy stops applying. This is the one change that must be handled before the upgrade rather than after: migrate each mirrored queue to a quorum queue, then delete the HA policies. rabbitmq-diagnostics check_if_cluster_has_classic_queue_mirroring_policy tells you whether any remain. We cover the tradeoffs in our classic vs quorum queues post.

Transient non-exclusive queues are deprecated. Non-durable queues that are not exclusive to a connection are flagged as a deprecated feature and can be denied by configuration. They still work in 4.x, but plan on declaring durable queues everywhere and using exclusive queues for genuinely per-connection state.

The default queue type. Declaring a queue without x-queue-type still gives you a classic queue unless the virtual host sets default_queue_type. Set it to quorum per vhost for new workloads, and make sure client code that declares queues passes an explicit x-queue-type so nobody is surprised by a vhost-level default.

AMQP 1.0 is a core protocol. In 4.0 the separate AMQP 1.0 plugin is no longer needed; 1.0 is implemented natively alongside 0-9-1 on the same listener. Existing 0-9-1 clients are unaffected. Teams that were running the old plugin should remove it from their enabled plugins list, and teams that want 1.0 should move to the maintained 1.0 client libraries rather than legacy ones.

Khepri as the metadata store. Khepri, the Raft-based replacement for Mnesia, shipped as experimental in 3.13 and is supported in 4.x, but it is opt-in. Nodes keep using Mnesia after the upgrade until you deliberately enable the khepri_db feature flag. Treat that as a separate change with its own test window, not a side effect of the version bump.

Feature flags must all be enabled first. A 3.13 cluster with any stable feature flag still disabled cannot join a 4.x node, and the 4.x node refuses to start against it. Enable everything before the first node moves.

Plugins and the management UI. Plugins compiled for 3.x need 4.x builds. The management plugin itself carries forward, but it drops the mirroring views and the AMQP 1.0 plugin becomes a no-op. Audit any community plugin before assuming it works.

MQTT 5. MQTT 5 support arrived in 3.13 and carries into 4.x. If you are coming from 3.12 or older, your MQTT clients gain it as part of the path.

Erlang. 4.x requires Erlang/OTP 26 or later. If your nodes are still on OTP 25, the Erlang upgrade happens as part of the rolling upgrade, one node at a time. See our note on Erlang 26 end of life and RabbitMQ before you pick a target.

Should we stay on 3.13 or upgrade to 4.x?

3.13 is the last 3.x series. The community support window for it is short, and once it closes there are no upstream security patches for any 3.x version. That is the honest constraint that drives the decision.

Staying on 3.13 is reasonable in exactly one case: you have a commercial or extended support arrangement that backports security fixes to the version you are running. Without that, a 3.13 cluster is a CVE clock. Our extended LTS support covers 3.8.x through 3.13.x with backported patches, which is what lets clients run older series on a schedule they control rather than one dictated by the upstream calendar. It buys time; it does not remove the need to plan the move.

Upgrade when all four of these are true:

  1. Mirrored classic queues are gone and no HA policies remain.
  2. Every stable feature flag is enabled on every node.
  3. Erlang is on OTP 26 or later, or you are ready to move it during the rolling upgrade.
  4. Client applications are on maintained library versions that behave correctly against quorum queues (correct handling of x-delivery-limit, dead lettering, and reconnect).

Upgrade sooner than your maintenance calendar suggests if you need AMQP 1.0 without the plugin, MQTT 5 on an older 3.x, or the 4.x quorum queue improvements, which include message priorities and a default delivery limit that stops poison messages from cycling forever.

If you are on 3.8 through 3.12, the answer is the same but the path is longer: get to 3.13 first, stabilise, then move to 4.x. We run both halves for clients and the upgrade service is scoped that way.

Whether staying is safe is a separate question from whether it is possible: is RabbitMQ 3.x still safe to run works through the end-of-life dates and the CVE exposure series by series. If you stay, extended LTS support for RabbitMQ 3.x keeps the version patched while the upgrade waits for a window.

The rolling upgrade runbook we use

This is the sequence we follow on client clusters. It assumes a three or five node cluster, quorum queues for anything that matters, and clients that reconnect on connection loss.

  1. Inventory. Record versions, Erlang versions, enabled plugins, and every policy. Run rabbitmq-diagnostics check_if_any_deprecated_features_are_used and rabbitmq-diagnostics check_if_cluster_has_classic_queue_mirroring_policy on any node. Both must come back clean before you continue.
  2. Enable all stable feature flags. rabbitmqctl enable_feature_flag all on one node applies cluster-wide. Confirm with rabbitmqctl list_feature_flags; anything still disabled blocks the upgrade.
  3. Convert mirrored classic queues to quorum queues, flow by flow. Quorum queues cannot be converted in place. For each flow, declare the quorum queue, repoint consumers, repoint producers, drain the old queue, delete it. Do this per application so a mistake affects one flow, not the estate.
  4. Verify the Erlang target. Confirm the OTP 26 or later package is available on every node and that it is the version your 4.x build was tested against.
  5. Export definitions and take a backup. rabbitmqctl export_definitions plus a filesystem backup of the data directory on every node. The definitions export is what you rebuild from if the rollback boundary is crossed.
  6. Upgrade one node at a time. Before stopping a node, run rabbitmq-upgrade await_online_quorum_plus_one so no quorum queue loses its majority while this node is out. Then rabbitmq-upgrade drain puts the node in maintenance mode, closes client connections gracefully, and transfers quorum queue leadership away. Stop the service, upgrade Erlang if needed, upgrade RabbitMQ, start it, and confirm it rejoined.
  7. Wait for quorum queue members to catch up. rabbitmq-queues quorum_status <queue> on the busiest queues, or rabbitmq-diagnostics check_if_node_is_quorum_critical on the next node you intend to stop. Do not start the next node until this passes.
  8. Verify clients reconnected. Connection counts in the management UI should return to baseline on the upgraded node. If a client library does not reconnect, fix it now, before the next node.
  9. Repeat for each remaining node. The cluster runs mixed 3.13 and 4.x during this window. Do not change policies, add queues, or enable anything new until the last node is done.
  10. Enable the new 4.x feature flags. After the final node is upgraded, rabbitmqctl enable_feature_flag all again. This is the rollback boundary: once a 4.x-only feature flag is enabled there is no downgrade path. Everything before this step can be reversed by restoring a node to 3.13.
rabbitmqctl enable_feature_flag all
rabbitmq-upgrade await_online_quorum_plus_one
rabbitmq-upgrade drain

Blue-green is the alternative when the cluster is small enough to rebuild, the definitions export is trustworthy, and you can afford to move clients by DNS or load balancer. It gives you a clean 4.x cluster and an intact 3.13 cluster to fall back to. We prefer it for clusters that have accumulated years of undocumented policies.

Either way, support covers the upgrade window with a 15-minute P1 response, which matters most between step 6 and step 10.

FAQ

Can I upgrade directly from RabbitMQ 3.13 to 4.x?

Yes. A rolling upgrade from 3.13.x to 4.0.x is supported, provided every stable feature flag is enabled, no classic queue mirroring policies remain, and Erlang is on OTP 26 or later. If you are on 3.12 or older you cannot skip to 4.x; upgrade to 3.13 first, enable its feature flags, then continue. The reason is that 4.x nodes only join clusters where the 3.13 feature flag set is fully enabled, and older series cannot satisfy that.

Can I stay on RabbitMQ 3.x?

You can, but only safely with a support arrangement that backports security fixes, because upstream patches for 3.x end with 3.13's community window. Our extended LTS support covers 3.8.x through 3.13.x with backported CVE patches for exactly this situation. Staying makes sense when a client migration, a compliance freeze, or a queue conversion needs more time than the upstream calendar allows. It does not make sense as a permanent state; plan the 4.x move on your own schedule.

How do you upgrade RabbitMQ without downtime?

Rolling upgrade, one node at a time. Enable all feature flags, remove mirrored classic queues, export definitions, then for each node run rabbitmq-upgrade await_online_quorum_plus_one, drain it, upgrade Erlang and RabbitMQ, restart, and wait for quorum queue members to catch up before touching the next node. Clients that reconnect on connection loss see a brief reconnect, not an outage. Blue-green, with a new 4.x cluster and a client cutover, is the option when the existing cluster is too tangled to upgrade in place.

Does RabbitMQ 4 require Erlang 26?

Yes. RabbitMQ 4.x requires Erlang/OTP 26 or later. If your 3.13 nodes are already on OTP 26 the Erlang step is a no-op; if they are on OTP 25, upgrade Erlang on each node during the same rolling window as the RabbitMQ package. Check the compatibility table for the exact 4.x patch release you are installing, since later 4.x releases raise the minimum. Our post on Erlang 26 end of life covers what that means for support timelines.

Free Consultation

Get Expert Eyes on Your RabbitMQ Cluster

Whether you're troubleshooting a production incident, planning a migration, or want a second opinion on your architecture — our team is ready. No pitch, just answers.

Email Us