// OSSeva Blog
MigrationRabbitMQ 3 to 4 Upgrade: The Supported Path From 3.12 and 3.13 to 4.3
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
| From | To | Supported? |
|---|---|---|
| 3.12.x | 3.13.x | Yes, rolling |
| 3.12.x | Any 4.x | No. Go to 3.13 first |
| 3.13.x | 4.0, 4.1 or 4.2 | Yes, rolling. 4.2 is the one to pick, because it is the only series that can go on to 4.3 |
| 3.13.x | 4.3 | No. "3.13.x users must first upgrade to 4.2.x, then to 4.3.x" |
| 4.0.x or 4.1.x | 4.2 | Yes, rolling |
| 4.2.x | 4.3 | Yes, rolling, once the khepri_db feature flag is enabled |
| 3.13.x with Khepri enabled | Any 4.x | No in-place upgrade. Use a blue-green deployment |
| 4.x | 3.13 | No. 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_dbis 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, withrabbitmqctl 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
| Release | Change | How to detect it |
|---|---|---|
| 4.1 | The initial AMQP 0-9-1 frame size before authentication rose from 4096 to 8192 bytes. Node.js amqplib older than 0.10.7 cannot connect | Search lockfiles for amqplib; look for clients that set frame_max below 8192 |
| 4.1 | Default MQTT maximum packet size dropped from 256 MiB to 16 MiB | Largest payload sent by MQTT publishers; mqtt.max_packet_size_authenticated in config |
| 4.2 | An AMQP 1.0 message without a header section is treated as non-durable | AMQP 1.0 clients not maintained by Team RabbitMQ; check that they set durable |
| 4.2 | Raft metrics for quorum queues and Khepri renamed, added or removed | Dashboards and alerts using rabbitmq_raft or rabbitmq_detailed_raft metrics |
| 4.2 | A node refuses to start if an authentication backend's plugin is not enabled; *.cacerts settings removed | auth_backends entries and cacerts keys in rabbitmq.conf |
| 4.3 | Non-durable, non-exclusive queues are rejected by default | check_if_any_deprecated_features_are_used; queues declared with durable=false and exclusive=false |
| 4.3 | Global QoS, queue_master_locator and two AMQP 1.0 address and filter behaviours denied by default | Global QoS use cannot be detected by the broker; search client code for basic.qos with global=true |
| 4.3 | CQv1 storage removed: x-queue-mode and x-queue-version=1 are rejected | Search declarations and policies for those arguments |
| 4.3 | Consumer timeouts no longer evaluated for classic queues and streams | Applications that rely on consumer_timeout to recover stuck classic-queue consumers |
| 4.3 | rabbitmqadmin v1 download endpoint removed | Scripts 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
- 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.
- 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.
- Roll each node to 4.2, one at a time:
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.# 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 - 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 - Move to Erlang 27 and the latest 4.2 patch if the first 4.2 hop stayed on Erlang 26.2.
- Enable Khepri on the healthy 4.2 cluster:
rabbitmqctl enable_feature_flag khepri_db. If the cluster had therabbitmq_amqp1_0plugin enabled on 3.13 and still serves AMQP 1.0 clients, the 4.3 release notes ask for at least one rolling restart afterrabbitmq_4.0.0is enabled and before 4.3. - Remove
cluster_partition_handlingkeys and anydeprecated_features.permit.*settings you do not intend to keep. - Roll each node to 4.3 with the same per-node steps, then run
enable_feature_flag allandrabbitmq-queues rebalance allagain.
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
Related articles
Kafka vs NATS (and JetStream): Design, Delivery, Performance and Where RabbitMQ Fits
October 8, 2026MigrationMongoDB vs MySQL vs PostgreSQL: Data Model, Transactions, Scaling, Licensing and Which to Choose
October 8, 2026MigrationPostgreSQL vs Aurora PostgreSQL vs RDS: Architecture, Billing, Version Support and When to Self-Manage
October 8, 2026Ready to get your open source under control?
Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.