// OSSeva Blog
MigrationUpgrading Erlang/OTP 26 to 27 or 28 Under RabbitMQ: Order, Packages and Testing
The short answer
Erlang/OTP 26 reached end of life on 26 May 2026, and fixes for later OTP advisories, including CVE-2026-89422, shipped for OTP 27, 28 and 29 only. Getting a RabbitMQ cluster onto OTP 27 or 28 depends on which broker release it runs, because every RabbitMQ release supports a fixed band of Erlang versions.
The rule is simple. Find a RabbitMQ release whose band includes both your current OTP and your target OTP. If the release you run already supports the target, upgrade Erlang. If it does not, upgrade RabbitMQ first, to a release that still runs on your current OTP, then upgrade Erlang. On community RabbitMQ 3.13.7 that means RabbitMQ always goes first.
Which RabbitMQ runs on which OTP
From RabbitMQ's Erlang version requirements page, as of 4 October 2026:
| RabbitMQ | Minimum Erlang | Maximum Erlang | Notes |
|---|---|---|---|
| 4.3.6 | 27.0 | 28.x | Latest community release; first with full Erlang 28 support |
| 4.3.3 to 4.3.5, 4.2.9, 4.2.10 | 27.0 | 27.x | Erlang 28 only for new clusters |
| 4.3.0 to 4.3.2, 4.2.0 to 4.2.8, 4.1.0 to 4.1.4, 4.0.4 to 4.0.9 | 26.2 | 27.x | Erlang 28 only for new clusters, from 4.2.0 |
| 4.0.1 to 4.0.3 | 26.2 | 26.2.x | |
| 3.13.x (public releases) | 26.0 | 26.2.x |
The third row is the bridge. Releases from 4.0.4 through 4.2.8, and 4.3.0 to 4.3.2, run on both OTP 26.2 and OTP 27, so a cluster on one of them can change its Erlang version without changing its broker version, and change it back.
The Erlang 28 caveat matters. For releases from 4.2.0 to 4.3.5, RabbitMQ says Erlang 28 is only supported for brand-new clusters, because upgrading a cluster that runs Khepri on Erlang 27 to Erlang 28 can hit a known issue affecting mixed-version clusters and rolling upgrades. RabbitMQ 4.3.6 is the first release with full Erlang 28 support, and the page also lists Erlang 29 support from 4.3.6, though not every package does yet. For an existing cluster, that makes OTP 27 the first target, with 28 as a separate roll once the cluster is on 4.3.6.
The 3.13.7 trap
RabbitMQ 3.13.7 is the last public 3.13 release, and community support for 3.13 ended on 30 September 2024. The public 3.13 releases support Erlang 26.0 to 26.2.x and nothing newer. Broadcom's knowledge base article 450171 says the 3.13 series is compatible with Erlang 27 starting with 3.13.8, but 3.13.8 and later are commercial releases for Tanzu RabbitMQ customers. Commercial support for 3.13 runs to 31 December 2029.
So a community 3.13.7 cluster cannot take OTP 27. Installing it anyway puts the broker outside its tested band. The route to a patched runtime goes through RabbitMQ 4.x, and that starts with the queue changes 4.0 requires.
The upgrade order from 3.13.7 on OTP 26
- Move off classic mirrored queues. RabbitMQ 4.0 removed classic queue mirroring, so every mirrored queue has to become a quorum queue or a stream first. See migrating classic mirrored queues to quorum queues and RabbitMQ 4.0 breaking changes.
- Enable every stable feature flag on 3.13.7. RabbitMQ's upgrade guide warns that the upgrade may fail otherwise.
rabbitmqctl list_feature_flags rabbitmqctl enable_feature_flag all - Upgrade RabbitMQ to 4.2.x, staying on OTP 26.2. RabbitMQ's upgrade guide says 3.13.x users must go to 4.2.x before 4.3.x. Choose a 4.2 release from 4.2.0 to 4.2.8, since 4.2.9 and 4.2.10 need Erlang 27.
- Upgrade Erlang to OTP 27, node by node, on the same 4.2 release. RabbitMQ recommends running the same Erlang major version on all nodes, so keep the mixed period short.
- Enable the new stable feature flags, then upgrade to 4.3.6, which requires Erlang 27.0 or later.
- Optionally, move to OTP 28 node by node once the whole cluster runs 4.3.6.
RabbitMQ's upgrade guide recommends upgrading Erlang together with RabbitMQ, so steps 3 and 4 can be combined: install the new broker and OTP 27 on each node in the same restart. Keeping them separate costs an extra rolling restart and gives you a cleaner rollback. If the Erlang change misbehaves, you can go back to OTP 26.2 on the same broker version.
From 4.0.4 to 4.1.x on OTP 26.2, the broker already accepts OTP 27, so Erlang can go first. Then upgrade RabbitMQ on the newer runtime.
Rolling each node
# Before stopping a node: confirm it is safe to take down
rabbitmq-diagnostics check_if_node_is_quorum_critical
rabbitmq-upgrade drain
# Stop, upgrade packages, start, then confirm both versions
rabbitmq-diagnostics status | grep -iE 'rabbitmq version|erlang'
rabbitmq-diagnostics erlang_version
# Wait for quorum queues to regain their replicas before the next node
rabbitmq-upgrade await_online_quorum_plus_one
Export definitions before you start (rabbitmqctl export_definitions /path/definitions.json), and keep the file with the change record.
Packaging
Where Erlang comes from matters as much as which version it is. Distribution packages often carry a different OTP from the one your broker needs, and an unattended package update can move the runtime under a running cluster.
- RHEL, Rocky, Alma and Fedora: Team RabbitMQ publishes a zero-dependency Erlang RPM, stripped of the parts RabbitMQ does not use, from GitHub and from its Yum repositories (the
modern-erlangrepositories for el/8 and el/9). RabbitMQ's documentation calls it the recommended option. The yum versionlock plugin can stop unexpected upgrades, though the docs warn that locking also holds back security fixes. - Debian and Ubuntu: Team RabbitMQ runs apt repositories with Erlang packages, and a Launchpad PPA that also carries arm64 builds. Use apt pinning in
/etc/apt/preferences.d/to choose the repository and hold the Erlang major version. - Containers: the RabbitMQ Docker image ships its own Erlang, so the OTP version changes with the image tag. Check it with
rabbitmq-diagnostics erlang_versionafter every image change.
Pin the OTP major in your configuration management, and make changing it an explicit step in the upgrade plan rather than a side effect of patching.
Test plan
- Build a staging cluster with the same node count, plugins, definitions and Erlang packaging as production, and run the full sequence there.
- Test TLS in both directions. Client connections to the broker on every listener (AMQP, MQTT, STOMP, streams, management UI), and the connections the broker makes itself: Shovel and Federation links, LDAP over TLS, OAuth 2 key fetches and inter-node TLS. A TLS library change often shows up first in cipher, certificate and hostname verification behaviour.
- Run your client libraries against the upgraded cluster, including old ones in rarely deployed services.
- Load test with production-like message sizes and rates, and compare publish latency, memory and scheduler use with the old runtime.
- Exercise failure: stop a node under load, partition one if your test environment allows it, and check that quorum queues elect leaders and clients recover.
- Check plugins, especially community plugins, against the new broker and OTP versions.
Rollback
The two halves roll back differently.
- Erlang on an unchanged broker: if the broker release supports both OTP versions, you can reinstall OTP 26.2 on each node and restart. Keep the old packages in your repository manager until the change has settled.
- The broker itself: once new feature flags are enabled they cannot be disabled, and nodes on an older release cannot rejoin. Enable new flags only after the cluster has run cleanly on the new version for a while. A full rollback after that means building a cluster on the old version from exported definitions and moving traffic to it. For large estates, RabbitMQ's blue-green approach, with a second cluster and Shovel or Federation moving messages across, gives you a rollback path for the whole step.
The next dates
OTP 27 reaches end of life on 20 May 2027 and OTP 28 on 20 May 2028. Community support for RabbitMQ 4.3 ends on 30 November 2026. A cluster that reaches 4.3.6 on OTP 27 this autumn should already be planning its next step.
If the queue migration cannot happen yet
For many 3.13 estates, the classic mirrored queue migration is the slow part, and the runtime has no patches while it runs. OSSeva ships patched Erlang/OTP 24, 25 and 26 builds with fixes for the ssl, ssh, public_key and crypto applications backported, matched and tested with the RabbitMQ 3.11 to 3.13 releases that depend on them, and patched RabbitMQ 3.13 builds alongside. Builds are signed and delivered through your own repository manager. Assure adds an OTP and broker compatibility matrix for your estate, a staged OTP upgrade plan with rollback, and VEX attestation for scanner findings. Operate adds 24/7 BEAM monitoring, a 15-minute P1 response and executed rolling OTP upgrades across your clusters. See Erlang/OTP support and RabbitMQ 3.x extended support.
Related
Tags
Related articles
Erlang/OTP Vulnerabilities by Version: CVEs for OTP 24 to 29 and the RabbitMQ Releases That Pin Them
October 5, 2026MigrationUpgrade Node.js 18 or 20 to 22 or 24: Breaking Changes, Steps and Rollback
October 5, 2026MigrationMigrate Redis to Valkey: A Step-by-Step Cutover With Rollback
October 5, 2026Ready to get your open source under control?
Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.