RabbitMQ
Synopsis
Creates a target that publishes log messages to RabbitMQ exchanges or queues with support for batching, routing, TLS encryption, and automatic retry logic. RabbitMQ is a widely-used open-source message broker for reliable message delivery.
Schema
- name: <string>
description: <string>
type: rabbitmq
pipelines: <pipeline[]>
status: <boolean>
properties:
url: <string>
exchange: <string>
routing_key: <string>
queue: <string>
content_type: <string>
delivery_mode: <integer>
mandatory: <boolean>
immediate: <boolean>
timeout: <integer>
batch_size: <integer>
max_retries: <integer>
retry_delay: <integer>
field_format: <string>
tls:
status: <boolean>
verify: <boolean>
server_name: <string>
ca_name: <string>
cert_name: <string>
key_name: <string>
passphrase: <string>
min_tls_version: <string>
max_tls_version: <string>
debug:
status: <boolean>
dont_send_logs: <boolean>
Configuration
The following fields are used to define the target:
| Field | Required | Default | Description |
|---|---|---|---|
name | Y | Target name | |
description | N | - | Optional description |
type | Y | Must be rabbitmq | |
pipelines | N | - | Optional post-processor pipelines |
status | N | true | Enable/disable the target |
Connection
| Field | Required | Default | Description |
|---|---|---|---|
url | Y | - | RabbitMQ server URL (e.g., amqp://localhost:5672 or amqps://host:5671) |
timeout | N | 30 | Connection timeout in seconds |
Routing Configuration
| Field | Required | Default | Description |
|---|---|---|---|
exchange | N* | - | RabbitMQ exchange name |
routing_key | N | - | Routing key for message delivery (defaults to queue name if queue is specified) |
queue | N* | - | RabbitMQ queue name (queue will be declared as durable) |
* = Conditionally required. Either exchange or queue must be specified. If queue is specified without routing_key, the queue name is used as the routing key.
Message Properties
| Field | Required | Default | Description |
|---|---|---|---|
content_type | N | application/json | Message content type |
delivery_mode | N | 2 | Delivery mode: 1 (non-persistent), 2 (persistent) |
mandatory | N | false | Require message to be routed to at least one queue |
immediate | N | false | Require immediate delivery to consumer (deprecated in RabbitMQ 3.x) |
Batch Configuration
| Field | Required | Default | Description |
|---|---|---|---|
batch_size | N | 1000 | Number of messages to batch before publishing (minimum 1) |
max_retries | N | 3 | Maximum retry attempts for failed publish operations |
retry_delay | N | 1 | Delay between retry attempts in seconds |
Processing
| Field | Required | Default | Description |
|---|---|---|---|
field_format | N | - | Data normalization format. See applicable Normalization section |
TLS Configuration
| Field | Required | Default | Description |
|---|---|---|---|
tls.status | N | false | Enable TLS encryption |
TLS material is resolved through the shared client builder, so these keys mean the same thing on every
target that uses it. They are nested under a tls: block.
| Field | Required | Default | Description |
|---|---|---|---|
tls.verify | N | true | Verify the server certificate. On by default — set it to false only to accept an untrusted certificate, and only where you control the network path |
tls.server_name | N | - | SNI hostname override for the handshake. Use it when the certificate's name does not match the address you connect to |
tls.ca_name | N | - | CA bundle used to verify the server certificate. When unset the host trust store is used; when set it replaces the host trust store rather than adding to it |
tls.cert_name | N* | - | Client certificate, for mutual TLS |
tls.key_name | N* | - | Client private key, for mutual TLS |
tls.passphrase | N | - | Passphrase for an encrypted client private key |
tls.min_tls_version | N | tls1.2 | Lowest protocol version accepted (tls1.0, tls1.1, tls1.2, tls1.3) |
tls.max_tls_version | N | tls1.3 | Highest protocol version accepted (tls1.0, tls1.1, tls1.2, tls1.3) |
* cert_name and key_name are individually optional but must be supplied together — a certificate
without its key, or a key without its certificate, is a configuration error.
Scheduling
See Scheduling and Pool Behavior for interval and cron fields shared by all targets.
Debug Options
| Field | Required | Default | Description |
|---|---|---|---|
debug.status | N | false | Enable debug logging |
debug.dont_send_logs | N | false | Process logs but don't send to target (testing) |
Details
The RabbitMQ target publishes log messages to RabbitMQ exchanges or directly to queues. Messages are accumulated in batches and published when the batch size is reached. Each message is published with automatic retry logic for handling transient failures.
The target maintains a persistent connection to the RabbitMQ server with thread-specific channels for concurrent operations. If a queue is specified during initialization, it is automatically declared as a durable queue.
Message timestamps are set to the log event epoch time, and messages can be configured as persistent (surviving broker restarts) or non-persistent for maximum throughput.
Prerequisites
- A running RabbitMQ server
- Network connectivity to the RabbitMQ server
- Valid authentication credentials (included in the URL)
- The exchange must already exist if publishing to an exchange. The target never creates exchanges
- TLS certificates if using encrypted connections
Either exchange or queue must be specified. When using queue, the queue is automatically declared as durable. When using exchange, ensure the exchange exists on the RabbitMQ server.
Both tls.cert_name and tls.key_name must be provided together when using client certificate authentication. Providing only one will result in a configuration error.
The immediate flag is deprecated in RabbitMQ 3.x and later. Setting it to true may cause errors with modern RabbitMQ servers.
Examples
Basic Queue
Minimum configuration for publishing to a queue:
targets:
- name: basic_rabbitmq
type: rabbitmq
properties:
url: "amqp://guest:guest@localhost:5672"
queue: "logs"
Exchange with Routing
Configuration for publishing to an exchange with routing key:
targets:
- name: exchange_rabbitmq
type: rabbitmq
properties:
url: "amqp://logger:password@rabbitmq.example.com:5672"
exchange: "logs.topic"
routing_key: "application.logs"
Persistent Messages
Configuration with persistent message delivery:
targets:
- name: persistent_rabbitmq
type: rabbitmq
properties:
url: "amqp://logger:password@rabbitmq.example.com:5672"
queue: "durable_logs"
delivery_mode: 2
With TLS
Configuration with TLS encryption:
targets:
- name: secure_rabbitmq
type: rabbitmq
properties:
url: "amqps://logger:password@rabbitmq.example.com:5671"
queue: "secure_logs"
tls:
status: true
verify: true
min_tls_version: "tls1.2"
With Client Certificate
Configuration using mutual TLS with client certificates:
targets:
- name: mtls_rabbitmq
type: rabbitmq
properties:
url: "amqps://logger:password@rabbitmq.example.com:5671"
queue: "secure_logs"
tls:
status: true
verify: true
cert_name: "client.pem"
key_name: "client-key.pem"
min_tls_version: "tls1.2"
Custom Batch Size
Configuration with custom batching and retry settings:
targets:
- name: batch_rabbitmq
type: rabbitmq
properties:
url: "amqp://logger:password@rabbitmq.example.com:5672"
queue: "highvolume_logs"
batch_size: 5000
max_retries: 5
retry_delay: 2
timeout: 60
With Normalization
Configuration using field normalization:
targets:
- name: normalized_rabbitmq
type: rabbitmq
properties:
url: "amqp://logger:password@rabbitmq.example.com:5672"
exchange: "logs.ecs"
routing_key: "normalized"
field_format: "ecs"
With Pipeline
Using a pipeline for additional log processing:
targets:
- name: pipeline_rabbitmq
type: rabbitmq
pipelines:
- enrich_logs
properties:
url: "amqp://logger:password@rabbitmq.example.com:5672"
queue: "enriched_logs"
Troubleshooting
This section covers the errors you are most likely to see with the rabbitmq target, what causes each one, and how to fix it.
Where to look:
- Director logs. Target errors are tagged with the target name and carry
"Section":"SenderPool". The part afterReason:, or after the last colon, is the actual cause. - The target's connection status in the web interface. It shows the same reason as the log line.
See Target Delivery Errors for how Director logs and retries target failures.
Whatever the broker reports reaches the log in the form Exception (<code>) Reason: "<text>". The number is the AMQP reply code, and it is the quickest way to tell the causes below apart. A few replies are rewritten before they are logged, so some entries send you to the broker's own log for the last word.
Which permission or setting is missing?
RabbitMQ grants permissions per virtual host, as a configure, write and read rule for each user. This target needs a user that can reach the virtual host, may configure the queue when you use queue mode, and may write to the exchange it publishes through. In queue mode that exchange is the default exchange and the routing key is the queue name.
| What you see | What the broker must allow | Scope |
|---|---|---|
Exception (403) with username or password not allowed | The user exists with that password and may connect from the Director host | Broker |
Exception (403) with no access to this vhost | The virtual host exists and the user has permission on it | Virtual host |
failed to declare queue with Exception (403), typically naming ACCESS_REFUSED | Configure permission matching the queue name | Virtual host, queue mode only |
failed to declare queue with Exception (406), typically naming PRECONDITION_FAILED | An existing queue that is durable and classic, not exclusive, not auto-delete, and declared with no extra arguments | The queue |
failed to publish message after 4 attempts or confirm channel closed before all broker acknowledgments were received | Write permission matching the exchange name, and an exchange that already exists | Virtual host and exchange |
| No error at all, and the queue stays empty | A queue bound to the exchange for the routing key you publish with | Exchange |
A user that only writes logs needs no read permission. rabbitmqctl set_permissions -p my_vhost logger ".*" ".*" "" grants configure and write on everything in my_vhost and nothing else. Narrow the first two patterns to the queue and exchange names once delivery works.
"username or password not allowed"
[Error] [director] [target-<target id>] [basic_rabbitmq] Failed to reinitialize target "basic_rabbitmq" (attempt 12). Reason: failed to connect to RabbitMQ: Exception (403) Reason: "username or password not allowed"
Cause: the broker refused the login. Credentials for this target live only in url, written as amqp://user:password@rabbitmq.example.com:5672/my_vhost. Either the user name or the password is wrong, the user no longer exists, or the broker does not accept that user from the Director host. The default guest user is typically restricted to connections made from the broker host itself, so a configuration that works in a local test fails as soon as Director runs elsewhere. The same message also appears when the broker closes the connection during login for an unrelated reason, so read the broker log for the refusal it recorded if the credentials are certainly correct.
Fix: correct the user and password in url, and percent-encode any reserved character in the password, as described under the URL entry below. Create a dedicated user for Director rather than using guest, and allow it from the Director host's address.
Nothing is sent while this lasts. Incoming data stays queued and is retried until you fix the cause.
"no access to this vhost"
[Error] [director] [target-<target id>] [basic_rabbitmq] Failed to reinitialize target "basic_rabbitmq" (attempt 3). Reason: failed to connect to RabbitMQ: Exception (403) Reason: "no access to this vhost"
Cause: the login succeeded, but the virtual host named in the url path does not exist, or the user has no permission on it. Both cases produce this one message, so check for the typo first and the permission second. The path is the virtual host: amqp://user:password@rabbitmq.example.com:5672 uses the default virtual host /, while amqp://user:password@rabbitmq.example.com:5672/my_vhost uses my_vhost. A / inside a virtual host name must be written as %2F.
Fix: correct the path, create the virtual host, or grant the user permission on it. A path such as /prod against a broker that hosts /production is the common cause.
Nothing is sent while this lasts, and the queued data is delivered once the next attempt connects.
"failed to declare queue" with a 403
[Error] [director] [target-<target id>] [basic_rabbitmq] Failed to reinitialize target "basic_rabbitmq" (attempt 2). Reason: failed to declare queue: Exception (403) Reason: "..."
Cause: in queue mode the target declares the queue on every start, and the broker refused the declaration. The reply text typically begins with ACCESS_REFUSED and names the queue, the virtual host and the user. The user is missing the configure permission for that queue name in that virtual host.
Fix: grant configure permission for the queue name. Creating the queue yourself first does not avoid this, because the declaration is always sent. If configure permission cannot be granted, publish through an exchange instead: set exchange and routing_key, remove queue, and have the broker owner bind the queue to that exchange.
Nothing is sent while this lasts, and the data stays queued.
"failed to declare queue" with a 406
[Error] [director] [target-<target id>] [basic_rabbitmq] Failed to reinitialize target "basic_rabbitmq" (attempt 4). Reason: failed to declare queue: Exception (406) Reason: "..."
Cause: a queue with that name already exists and was declared with different properties. This target always declares a durable classic queue that is not exclusive, not auto-delete, and carries no arguments, so a queue created any other way is refused. The reply text typically begins with PRECONDITION_FAILED and names the property that differs, such as durable or x-queue-type. A quorum queue, a stream, a transient queue, and a queue created with arguments such as a message TTL or a dead-letter exchange all fail here.
Fix: pick one of these.
- Delete the existing queue and let Director declare it.
- Recreate it as a plain durable classic queue with no arguments.
- Keep the queue as it is and publish through an exchange. Set
exchangeandrouting_key, removequeue, and bind the existing queue to the exchange. Nothing is declared in that mode, so the queue's own properties no longer matter.
Nothing is sent while this lasts. The mismatch does not heal on its own, so the target retries the same declaration until you change the queue or the configuration.
"failed to publish message after 4 attempts", or the confirm channel closing
[Error] [director] [target-<target id>] [exchange_rabbitmq] Sender worker 1 execute() failed for exchange_rabbitmq: target broken: failed to finalize target cache: failed to publish message after 4 attempts, last error: Exception (504) Reason: "channel/connection is not open"
[Error] [director] [target-<target id>] [exchange_rabbitmq] Sender worker 0 execute() failed for exchange_rabbitmq: target broken: failed to finalize target cache: confirm channel closed before all broker acknowledgments were received
Cause: the broker rejected a publish and closed the channel, and what reaches the log is the closed channel rather than the rejection behind it. The second form appears when the close arrives while the target is waiting for acknowledgements, which is what you see with small batches. The count in the first form is max_retries plus one attempt. The real reason is in the broker's log, and it is typically one of these.
- The exchange does not exist. The target never creates exchanges, so the name in
exchangemust already be present. The broker typically answers with a 404 namingNOT_FOUND. - The user has no write permission on the exchange. In
queuemode that is the default exchange. The broker typically answers with a 403 namingACCESS_REFUSED. - The message is larger than the broker's maximum message size. There is no size limit on the Director side, so this ceiling is the broker's own. It typically answers with a 406 naming
PRECONDITION_FAILEDand the two sizes. immediateis set totrue. RabbitMQ 3.0 and later refuse it, typically with a 540 namingNOT_IMPLEMENTED, and close the connection on the first publish. Leaveimmediateat its default offalse.- The connection was closed from outside. An operator closed it, the broker restarted, or the network dropped.
Fix: open the Management UI, then immediate, whichever the reason calls for.
The batch is not lost. It is queued again and retried until it succeeds. The whole batch is re-published each time, so messages the broker had already accepted can arrive twice after an outage. Make your consumers idempotent.
"timed out after 30s waiting for broker confirmations"
[Error] [director] [target-<target id>] [batch_rabbitmq] Sender worker 4 Finalize failed on flush for target "batch_rabbitmq": timed out after 30s waiting for broker confirmations (137 of 1000 received)
Cause: the target waits for the broker to confirm every message, and allows 30 seconds between two consecutive confirmations. The broker took the messages and then stopped confirming them. A memory or disk alarm is the usual reason, because an alarmed node blocks publishers. An overloaded node, or a quorum queue that has lost its quorum, looks the same. The numbers in brackets show how far the batch got.
Fix: check the broker's alarms in the Management UI or with rabbitmqctl status. Free disk space or memory, raise the broker's watermarks, and add consumers so the queues drain. This 30 second limit is fixed, and it is not the timeout setting, which only bounds opening the connection.
A related message, broker NACKed 12 of 1000 messages, means the broker declined to store part of the batch. Check the health of the queue's node and the queue's overflow policy. In both cases the batch is retried until the broker confirms it, and messages the broker already stored can be delivered twice.
"dial tcp" with no such host, connection refused, or a timeout
[Error] [director] [target-<target id>] [basic_rabbitmq] Failed to reinitialize target "basic_rabbitmq" (attempt 7). Reason: failed to connect to RabbitMQ: dial tcp: lookup rabbitmq.example.com: no such host
Cause: the connection was never opened. no such host means the name does not resolve. connect: connection refused means nothing is listening on that port. i/o timeout means the connection did not complete within timeout, which defaults to 30 seconds and usually points at a firewall. The exact wording comes from the operating system of the Director host, so it differs between Linux and Windows.
Fix: check the host name and the port in url. An amqp:// URL uses port 5672 and an amqps:// URL uses 5671 unless you write a port yourself. Open that port from the Director host to the broker, and raise timeout on slow links. The connection is made to the broker directly, so HTTP_PROXY and HTTPS_PROXY are ignored and a proxy cannot carry it.
Nothing is sent while this lasts, and the data stays queued.
"tls: failed to verify certificate" and other TLS errors
[Error] [director] [target-<target id>] [secure_rabbitmq] Failed to reinitialize target "secure_rabbitmq" (attempt 2). Reason: failed to connect to RabbitMQ: tls: failed to verify certificate: x509: certificate signed by unknown authority
Cause: the TLS handshake failed. Match the text against the cause.
| Text | Cause |
|---|---|
x509: certificate signed by unknown authority | The broker's certificate comes from a private CA the Director host does not trust |
x509: certificate is valid for ..., not ... | The host name in url is not one of the names in the broker's certificate |
tls: first record does not look like a TLS handshake | An amqps:// URL is pointed at the plaintext port |
remote error: tls: certificate required or remote error: tls: bad certificate | The broker wants a client certificate, or it rejected the one presented |
tls: server selected unsupported protocol version ... | tls.min_tls_version is above what the broker offers |
Fix: set tls.ca_name to the CA that signed the broker's certificate, or tls.server_name to the name the certificate carries, or correct the port to 5671. For a broker that requires client certificates, set tls.cert_name and tls.key_name together, and tls.passphrase when the key is encrypted. For certificate-based login, add ?auth_mechanism=external to url. If the broker offers only that mechanism while the URL logs in with a password, the connection fails with Exception (403) Reason: "SASL could not negotiate a shared mechanism" instead.
Nothing is sent while this lasts, and the data stays queued.
TLS is chosen by the URL scheme, not by tls.status. An amqp:// URL always connects in plain text and the whole tls block is ignored, so the password in url crosses the network unprotected. Use amqps:// whenever you set tls.status: true.
"AMQP scheme must be either 'amqp://' or 'amqps://'" and other URL problems
[Error] [director] [target-<target id>] [basic_rabbitmq] Failed to reinitialize target "basic_rabbitmq" (attempt 1). Reason: failed to connect to RabbitMQ: AMQP scheme must be either 'amqp://' or 'amqps://'
Cause: url could not be read. One value carries the scheme, the credentials, the host, the port and the virtual host, so a single stray character stops the target before it reaches the broker.
| Reason text | Cause |
|---|---|
AMQP scheme must be either 'amqp://' or 'amqps://' | The URL has no scheme, or it starts with http:// |
URI must not contain whitespace | A space in the URL, most often in the password or the virtual host. Write it as %20 |
parse ...: invalid port ... | A reserved character in the password ended the host part early, or the port is not a number |
unsupported auth_mechanism: ... | ?auth_mechanism= holds a value other than PLAIN, AMQPLAIN or EXTERNAL |
Fix: percent-encode every reserved character in the password. Write # as %23, ? as %3F, / as %2F and % as %25. Then check that the port is numeric. Nothing is sent while this lasts, and the data stays queued.
When the URL cannot be read, the value that failed is part of the error, and that value contains the password. The Director log and the connection status in the web interface then show the password in clear. Correct the URL promptly, and change the password if those logs were exported or shared.
Other reasons the target does not start
These reach you through the same retry loop as a connection failure. Nothing is sent while any of them lasts.
| Reason text | Fix |
|---|---|
url is required for rabbitmq target | Set url |
either exchange or queue must be specified for rabbitmq target | Set one of the two |
batch_size must be greater than 0 for rabbitmq target | Remove batch_size to take the default of 1000, or set at least 1 |
delivery_mode must be either 1 (non-persistent) or 2 (persistent) | Use 1 or 2 |
both tls.cert_name and tls.key_name must be provided together or omitted together | Set both, or neither |
failed to load TLS certificate: ... | The CA, the certificate or the key could not be read. Check the file names, the passphrase, and that tls.min_tls_version is not above tls.max_tls_version |
failed to create channel: ... or failed to create thread-specific channel: ... | The connection closed immediately after it opened. Check the broker's connection limits and its log |
failed to enable publisher confirms: ... | The broker does not offer publisher confirms. This target requires them, so it needs RabbitMQ rather than another AMQP broker |
The broker accepts the connection but no messages arrive
Nothing fails here, so there is no error to search for. Check the following in order.
-
The routing key matches no binding. In
exchangemode the broker accepts a message it cannot route, discards it, and acknowledges it anyway. The target cannot see that the message was discarded, so it counts it as delivered and Events Out keeps rising while the queue stays empty. Settingmandatory: truedoes not change this. On the broker, bind a queue to the exchange for the routing key you publish with, watch the exchange's unroutable counters, and consider an alternate exchange so that unroutable messages are kept rather than dropped. -
routing_keyis set alongsidequeue. Withqueuealone, the routing key is the queue name and the message lands in the queue. If you also setrouting_keyto something else, the message is published with that key instead, no queue answers to it, and the broker discards and acknowledges it exactly as above. Removerouting_keywhen you publish to a queue. -
debug.dont_send_logsis enabled. Records are processed by the pipeline and then discarded before anything is published. No counter moves, nothing reaches the broker, and the target reports healthy. The only trace is one line at startup, and only whendebug.statusis enabled as well.Log sending is disabled for this target (basic_rabbitmq). Logs will be processed by the pipeline but will not be sent to the target. -
The queue drops what it receives. A bounded queue with an overflow policy typically discards messages once it is full, and the broker acknowledges them all the same. Check the queue's length limit and its overflow policy on the broker, and confirm a consumer is draining it.