RabbitMQ Error Guide: 'unknown exchange type x-delayed-message' Missing Plugin
Fix RabbitMQ unknown exchange type errors for x-delayed-message and x-consistent-hash: the exchange-type plugin is missing or disabled. Enable and verify it.
- #rabbitmq
- #troubleshooting
- #errors
- #plugins
Exact Error Message
A client tries to declare an exchange whose type is provided by a plugin that the broker has not loaded, and the channel is closed with a 503:
Channel error on connection <0.27182.0> (10.0.4.21:51544 -> 10.0.4.7:5672, vhost: '/', user: 'app'):
operation exchange.declare caused a channel exception command_invalid:
unknown exchange type 'x-delayed-message'
The same failure appears for other plugin-backed types, most commonly the consistent-hash exchange:
operation exchange.declare caused a channel exception command_invalid:
unknown exchange type 'x-consistent-hash'
What the Error Means
RabbitMQ ships with four built-in exchange types: direct, fanout, topic, and headers. Any other type — anything prefixed with x- like x-delayed-message, x-consistent-hash, x-random, or x-recent-history — is registered by a plugin. When a client declares an exchange with such a type, the broker looks up a registered exchange-type behaviour matching that string. If no enabled plugin has registered it, the broker has no implementation to instantiate and raises command_invalid (AMQP reply code 503) with unknown exchange type.
This is purely a broker capability problem, not a client bug. The argument you sent is valid syntax; the broker simply does not know how to fulfill it because the plugin is missing, not enabled, or failed to load. Unlike a precondition_failed, this error happens even on the very first declare — there is no pre-existing exchange to conflict with.
A subtle trap: the delayed-message plugin is a community plugin distributed as a separate .ez file. It is not bundled with RabbitMQ, so even a correctly run rabbitmq-plugins enable will fail if the file was never copied into the plugins directory.
Common Causes
- The plugin is installed but not enabled.
rabbitmq_consistent_hash_exchangeships with the broker but is off by default. - The community plugin file is missing entirely.
rabbitmq_delayed_message_exchangeis a separate download and must be placed in the plugins directory before it can be enabled. - A version mismatch. The plugin
.ezwas built for a different RabbitMQ/Erlang version and silently fails to load. - Enabled on one node only. In a cluster, the plugin must be enabled on every node a client might connect to.
- The broker was upgraded and the offline
enabled_pluginsset was lost or the community.ezwas not re-copied. - A typo in the type string (for example
x-delay-messageinstead ofx-delayed-message).
How to Reproduce the Error
On a stock broker with no extra plugins enabled, declare a delayed exchange:
# Fails with command_invalid: unknown exchange type 'x-delayed-message'
rabbitmqadmin declare exchange name=jobs type=x-delayed-message \
arguments='{"x-delayed-type":"direct"}'
*** Error: 503 unknown exchange type 'x-delayed-message'
The same occurs for type=x-consistent-hash until the corresponding plugin is enabled on the node you connect to.
Diagnostic Commands
List the exchange-type plugins and whether they are enabled and running:
# Show all plugins; [E*] means enabled and running
rabbitmq-plugins list -v | grep -i 'exchange'
[ ] rabbitmq_consistent_hash_exchange 4.0.5
[ ] rabbitmq_delayed_message_exchange 4.0.1
Empty brackets mean the plugin is present but not enabled. If a plugin you expect is absent from the list entirely, its .ez file is missing from the plugins directory:
# Locate the plugins directory and confirm the .ez file exists
rabbitmq-diagnostics environment | grep -i plugins_dir
ls -1 "$(rabbitmq-diagnostics environment | sed -n 's/.*plugins_dir,"\(.*\)".*/\1/p')" | grep -i 'delayed\|consistent'
Check that the plugin actually loaded without an Erlang version error:
sudo journalctl -u rabbitmq-server --since '-20min' | grep -i 'plugin\|delayed\|consistent\|badmatch'
Confirm which node the client reached, since a per-node enable gap produces intermittent failures:
rabbitmqctl list_connections name peer_host node
Step-by-Step Resolution
Step 1: Confirm whether the plugin is present
Run rabbitmq-plugins list -v and look for the type’s plugin. If it appears with empty brackets, it just needs enabling. If it does not appear at all, the file is missing and must be installed first.
Step 2: For built-in plugins, enable it
The consistent-hash exchange ships with RabbitMQ, so a single enable command activates it:
sudo rabbitmq-plugins enable rabbitmq_consistent_hash_exchange
Step 3: For the community delayed-message plugin, install the .ez first
Download the .ez matching your exact RabbitMQ major version, place it in the plugins directory shown by plugins_dir, set correct ownership, then enable it. (Run the file-copy step with your platform’s package tooling; it is not a read-only operation.) Verify presence:
ls -1 /usr/lib/rabbitmq/plugins/ | grep delayed
rabbitmq_delayed_message_exchange-4.0.1.ez
Then enable it:
sudo rabbitmq-plugins enable rabbitmq_delayed_message_exchange
Step 4: Enable on every node in a cluster
rabbitmq-plugins enable affects the local node by default. Repeat on each node, or use --node for remote nodes, so any connection target supports the type.
Step 5: Verify the plugin is enabled and running
rabbitmq-plugins list -v | grep -i 'delayed\|consistent'
[E*] rabbitmq_delayed_message_exchange 4.0.1
The [E*] marker confirms the plugin is enabled and running.
Step 6: Redeclare the exchange
Reconnect the client and declare the exchange again. With the plugin loaded the broker now resolves the type and the channel stays open.
Prevention and Best Practices
- Bake plugin enablement into provisioning. Manage
enabled_plugins(orrabbitmqctl-driven enablement) in your config management so it survives rebuilds. - Ship community
.ezfiles as a versioned artifact pinned to the broker version, and re-copy them as part of every upgrade. - Enable plugins cluster-wide, not on a single node, to avoid intermittent failures behind a load balancer.
- Verify after upgrades. RabbitMQ and Erlang version bumps can break a community plugin built for the old version — check
rabbitmq-plugins list -vpost-upgrade. - Add a startup readiness check that asserts the required exchange types are available before the application begins publishing.
- Document which exchange types your topology depends on so the dependency is visible during environment setup.
Related Errors
- PRECONDITION_FAILED - inequivalent arg for exchange — once the plugin is enabled, a type mismatch against an existing exchange produces this 406 instead.
- NOT_FOUND - no exchange — publishing to an exchange that was never successfully declared because the type failed.
command_invalidon other operations — the same 503 class covers protocol-level invalid commands beyond exchange types.
Frequently Asked Questions
Why is x-delayed-message not just built in? It is a community-maintained plugin, not part of the core distribution. You must download the .ez separately and match it to your broker version before enabling it.
I enabled the plugin but still get the error — why? The most common reasons are enabling it on only one cluster node, or an .ez built for a different RabbitMQ/Erlang version that failed to load. Check the broker log for a load error and confirm [E*] on every node.
Does enabling the plugin require a broker restart? Enabling generally takes effect without a full restart, but the plugin must be loadable. If it was just copied in, confirm it appears in rabbitmq-plugins list and shows as running.
Is x-consistent-hash also a community plugin? No — rabbitmq_consistent_hash_exchange ships with RabbitMQ. It only needs to be enabled, not downloaded.
How do I know which node the client hit? Use rabbitmqctl list_connections name peer_host node. If different connections land on different nodes and only some fail, you have a per-node enablement gap.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.