Back to blog

// OSSeva Blog

Migration

RabbitMQ 3 to 4 Upgrade: The Supported Path From 3.12 and 3.13 to 4.3

Matt Reynolds10 min read

The short answer

RabbitMQ 4.3 can only be reached from 4.2, and 3.13 can only reach 4.x at 4.0, 4.1 or 4.2. So the supported route from 3.x is 3.12 to 3.13, 3.13 to 4.2, then 4.2 to 4.3, as rolling upgrades with all stable feature flags enabled before each step. Three things stop clusters on the way: classic mirrored queues, which 4.0 removed; Khepri, which a 3.13 cluster must not have enabled and which a 4.2 cluster must have enabled before 4.3; and the Erlang runtime, which moves from OTP 26 to OTP 27 along the way.

RabbitMQ does not support downgrades. Once a node has run 4.x, the way back is a second cluster, not a reinstall, so plan a blue-green fallback before the first node moves.

Upgrade paths

FromToSupported?
3.12.x3.13.xYes, rolling
3.12.xAny 4.xNo. Go to 3.13 first
3.13.x4.0, 4.1 or 4.2Yes, rolling. 4.2 is the one to pick, because it is the only series that can go on to 4.3
3.13.x4.3No. "3.13.x users must first upgrade to 4.2.x, then to 4.3.x"
4.0.x or 4.1.x4.2Yes, rolling
4.2.x4.3Yes, rolling, once the khepri_db feature flag is enabled
3.13.x with Khepri enabledAny 4.xNo in-place upgrade. Use a blue-green deployment
4.x3.13No. Downgrades are not supported

Aim for 4.3. Community support for 4.0, 4.1 and 4.2 has already ended (4.2 on 31 July 2026), and 4.3 has community support until 31 January 2027, so a cluster that stops at 4.2 is out of community support on arrival. The RabbitMQ end-of-life chart has every date.

Pre-upgrade checklist

Run these on 3.13 before anything changes. Each one maps to a blocker further down.

# Broker and runtime on every node
rabbitmq-diagnostics server_version -q
rabbitmq-diagnostics erlang_version -q

# Feature flags: every stable flag must show as enabled
rabbitmqctl -q --formatter pretty_table list_feature_flags

# Mirroring policies, per virtual host
rabbitmqctl list_policies -p / | grep -E "ha-mode|ha-params|ha-sync-mode"

# Deprecated features actually in use (exits non-zero if any)
rabbitmq-diagnostics check_if_any_deprecated_features_are_used

# Cluster health
rabbitmqctl cluster_status
rabbitmq-diagnostics check_local_alarms

# A copy of the definitions to rebuild from
rabbitmqctl export_definitions /var/backups/rabbitmq/definitions-3.13.json

Record the number of queues and messages per virtual host as well. After each hop you compare against it. Back up each node's data directory while the node is stopped.

Blocker 1: classic mirrored queues

4.0 removed classic queue mirroring. On 4.x an ha-mode policy replicates nothing, so a queue that relied on it for availability becomes a single-node queue the moment the cluster is upgraded. Every mirrored queue has to become a quorum queue or a stream while the cluster is still on 3.13.

How to detect it: the list_policies check above, run for every virtual host, and check_if_any_deprecated_features_are_used, which reports mirroring when it is in use. The work itself is covered in migrating classic mirrored queues to quorum queues. The other 4.0 changes (16 MiB default maximum message size, a delivery limit of 20 on quorum queues, AMQP 1.0 in core) are listed with their checks in RabbitMQ 4.0 breaking changes, and they all apply when you go straight from 3.13 to 4.2.

Blocker 2: feature flags

All stable feature flags must be enabled before an upgrade, or the upgrade may fail. A cluster that was upgraded in the past without enabling the new flags afterwards is the usual cause. Enabling them is safe to repeat:

rabbitmqctl enable_feature_flag all
rabbitmqctl -q --formatter pretty_table list_feature_flags

enable_feature_flag all enables stable flags only. That matters for the next blocker, because khepri_db is opt-in and is not switched on by it.

Blocker 3: Khepri, in both directions

Khepri is the Raft-based metadata store that replaces Mnesia. It affects the upgrade twice:

  • On 3.13 it must be off. Khepri was experimental in 3.13 and its data model changed for 4.0, so a 3.13 cluster with Khepri enabled cannot be upgraded in place. Check with rabbitmqctl list_feature_flags | grep khepri_db. If it shows enabled, the move to 4.x is a blue-green deployment to a new cluster.
  • On 4.2 it must be on. 4.3 removed Mnesia completely, and khepri_db is one of the flags 4.3 requires. A 3.13 cluster upgraded to 4.2 keeps using Mnesia; only new 4.2 clusters start on Khepri. Enable it on 4.2, after the cluster is healthy, with rabbitmqctl enable_feature_flag khepri_db.

Enabling Khepri is one-way: RabbitMQ does not support going back to Mnesia. It also changes availability. With Khepri, a majority of nodes must be online for the cluster to be available, and the cluster_partition_handling settings are accepted by 4.3 but have no effect. Remove them from rabbitmq.conf.

Blocker 4: the Erlang runtime

3.13 runs on Erlang 26.0 to 26.2.x. 4.2.0 to 4.2.8 run on 26.2 to 27.x, 4.2.9 and 4.2.10 need 27.0 or later, and 4.3.6 needs 27.0 and supports up to 28.x. Erlang 26 is no longer supported by RabbitMQ.

The practical sequence is to move a 3.13 cluster on Erlang 26.2 to a 4.2 release that still accepts 26.2, then upgrade Erlang to 27 together with the latest 4.2 patch, then go to 4.3. RabbitMQ recommends upgrading Erlang together with RabbitMQ and keeping the same Erlang major on every node outside the upgrade window. Erlang 28 with 4.3.3 to 4.3.5 is only supported for brand new clusters, so a rolling upgrade should stay on 27 until 4.3.6. The full matrix, and why 3.13 has no supported runtime left, is in RabbitMQ and Erlang version compatibility.

Breaking changes after 4.0, and how to detect each

ReleaseChangeHow to detect it
4.1The initial AMQP 0-9-1 frame size before authentication rose from 4096 to 8192 bytes. Node.js amqplib older than 0.10.7 cannot connectSearch lockfiles for amqplib; look for clients that set frame_max below 8192
4.1Default MQTT maximum packet size dropped from 256 MiB to 16 MiBLargest payload sent by MQTT publishers; mqtt.max_packet_size_authenticated in config
4.2An AMQP 1.0 message without a header section is treated as non-durableAMQP 1.0 clients not maintained by Team RabbitMQ; check that they set durable
4.2Raft metrics for quorum queues and Khepri renamed, added or removedDashboards and alerts using rabbitmq_raft or rabbitmq_detailed_raft metrics
4.2A node refuses to start if an authentication backend's plugin is not enabled; *.cacerts settings removedauth_backends entries and cacerts keys in rabbitmq.conf
4.3Non-durable, non-exclusive queues are rejected by defaultcheck_if_any_deprecated_features_are_used; queues declared with durable=false and exclusive=false
4.3Global QoS, queue_master_locator and two AMQP 1.0 address and filter behaviours denied by defaultGlobal QoS use cannot be detected by the broker; search client code for basic.qos with global=true
4.3CQv1 storage removed: x-queue-mode and x-queue-version=1 are rejectedSearch declarations and policies for those arguments
4.3Consumer timeouts no longer evaluated for classic queues and streamsApplications that rely on consumer_timeout to recover stuck classic-queue consumers
4.3rabbitmqadmin v1 download endpoint removedScripts that fetch rabbitmqadmin from the management plugin

A deprecated feature that is denied by default can be permitted again with a deprecated_features.permit.* key, set on every node before the upgrade. Treat that as a bridge with an end date, since denied features are the next ones to be removed.

The procedure: 3.13 to 4.2 to 4.3

  1. Get to the latest 3.13 patch you have, with all stable feature flags enabled and no mirroring policies left. Clusters on 3.12 do a 3.12 to 3.13 rolling upgrade first.
  2. Prepare packages. Stage the 4.2 packages and a compatible Erlang in your repository or image registry before you start, so every node gets the same build.
  3. Roll each node to 4.2, one at a time:
    # Block until shutting this node down keeps quorum everywhere
    rabbitmq-upgrade await_online_quorum_plus_one
    
    # Maintenance mode: close client connections and move quorum queue
    # leaders off the node. The restart below ends maintenance mode.
    rabbitmq-upgrade drain
    
    sudo systemctl stop rabbitmq-server
    # install Erlang (if changing) and RabbitMQ 4.2 packages here
    sudo systemctl start rabbitmq-server
    
    rabbitmq-diagnostics check_running
    rabbitmqctl cluster_status
    rabbitmq-diagnostics check_local_alarms
    Watch the log on each node before moving on. Mixed 3.13 and 4.2 clusters are a mechanism for the rolling upgrade, not a state to leave running.
  4. Finish 4.2. When every node runs 4.2, enable the new stable flags and spread queue leaders again:
    rabbitmqctl enable_feature_flag all
    rabbitmq-queues rebalance all
  5. Move to Erlang 27 and the latest 4.2 patch if the first 4.2 hop stayed on Erlang 26.2.
  6. Enable Khepri on the healthy 4.2 cluster: rabbitmqctl enable_feature_flag khepri_db. If the cluster had the rabbitmq_amqp1_0 plugin enabled on 3.13 and still serves AMQP 1.0 clients, the 4.3 release notes ask for at least one rolling restart after rabbitmq_4.0.0 is enabled and before 4.3.
  7. Remove cluster_partition_handling keys and any deprecated_features.permit.* settings you do not intend to keep.
  8. Roll each node to 4.3 with the same per-node steps, then run enable_feature_flag all and rabbitmq-queues rebalance all again.

Clear the browser cache for the management UI after each hop. RabbitMQ notes that a stale UI can throw JavaScript errors.

Rollback limits

RabbitMQ does not test or support downgrades, and it warns that even some patch releases could not be downgraded to the previous patch. Enabling feature flags makes this stricter, and enabling Khepri cannot be undone. The realistic fallback is a blue-green deployment: build the 4.x cluster beside the old one, sync definitions, move consumers and then publishers, and keep the old cluster until you are satisfied. From 4.2 there is tooling for this in rabbitmqadmin v2. RabbitMQ requires blue-green for 3.13 clusters that use Khepri, and points 3.13 clusters still moving off mirrored queues to it as well.

Where OSSeva fits

The upgrade is usually blocked by the queue migration, an ISV that has not certified 4.x, or the Erlang change, not by the commands above. OSSeva for RabbitMQ ships patched builds of community RabbitMQ for 3.8 through 3.13 and for the 4.0, 4.1 and 4.2 lines that are past community support, with Erlang/OTP builds that receive their own CVE patches, so the version you run stays patched while the path above is worked through. OSSeva Assure adds version upgrade planning and an architecture audit; OSSeva Operate adds 24/7 monitoring, runbooks and a 15-minute P1 response. Pricing is per cluster; book a discovery call for a quote. For 3.13 specifically, see RabbitMQ 3.x extended support and RabbitMQ 3.13 end of life.

Frequently asked questions

Can I upgrade RabbitMQ 3.13 directly to 4.3?

No. 4.3 only accepts upgrades from 4.2.x. Upgrade 3.13 to 4.2 first, enable all stable feature flags and Khepri, then go to 4.3.

Can I upgrade RabbitMQ 3.12 to 4.0?

No. 3.12 goes to 3.13 first. Every 4.x series that accepts 3.x upgrades accepts them from 3.13 only.

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

3.12 to 3.13, 3.13 to 4.2, 4.2 to 4.3. Older 3.x lines step through each minor series: 3.8 to 3.9, 3.9 to 3.10, 3.10 to 3.11, then 3.11.18 or later to 3.12.

Do I have to migrate mirrored queues before upgrading to RabbitMQ 4?

Yes, if you need those queues replicated. Mirroring was removed in 4.0, so mirrored classic queues become single-node queues after the upgrade. Move them to quorum queues on 3.13.

Is Khepri required in RabbitMQ 4.3?

Yes. 4.3 removed Mnesia, and the khepri_db feature flag must be enabled on 4.2 before the upgrade. It cannot be turned off afterwards.

Which Erlang version does RabbitMQ 4.3 need?

Erlang 27.0 or later for current 4.3 releases. 4.3.6 supports up to Erlang 28.x.

Can I downgrade from RabbitMQ 4 to 3.13?

No. Downgrades are not supported. Keep the old cluster running in a blue-green setup until the new one has proved itself.

Tags

RabbitMQRabbitMQ 4UpgradeKhepriErlang/OTP

Ready to get your open source under control?

Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.