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.
The target sends over AMQP 0-9-1 by default. With protocol: "1.0" it sends over AMQP 1.0 instead, to brokers such as ActiveMQ Artemis and Classic, Amazon MQ for ActiveMQ, Solace, and RabbitMQ 4. See Protocol.
type: amqp is this target under the protocol's name: the same keys, defaults and behavior, under either protocol. The AMQP device is its listener counterpart.
Schema
- name: <string>
description: <string>
type: rabbitmq
pipelines: <pipeline[]>
status: <boolean>
properties:
protocol: <string>
url: <string>
exchange: <string>
routing_key: <string>
queue: <string>
bind_queue: <boolean>
binding_key: <string>
content_type: <string>
delivery_mode: <integer>
mandatory: <boolean>
immediate: <boolean>
settlement: <string>
timeout: <integer>
batch_size: <integer>
max_retries: <integer>
retry_delay: <integer>
disable_retries: <boolean>
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 or amqp | |
pipelines | N | - | Optional post-processor pipelines |
status | N | true | Enable/disable the target |
Connection
| Field | Required | Default | Description |
|---|---|---|---|
protocol | N | 0-9-1 | The AMQP the target sends over: 0-9-1 or 1.0. Left out or empty, the target sends over AMQP 0-9-1, as before. An unquoted 1.0, which YAML and JSON read as the number 1, is read as 1.0. Any other value is a configuration error: protocol must be 0-9-1 or 1.0. See Protocol |
url | Y | - | RabbitMQ server URL (e.g., amqp://localhost:5672 or amqps://host:5671). Under 1.0, only amqp:// or amqps://, and its path, if any, is the virtual host (RabbitMQ 4) |
settlement | N | at_least_once | protocol: "1.0" only: at_least_once or presettled. Refused when set under 0-9-1. See Settlement |
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) |
bind_queue | N | false | Bind queue to exchange when the target starts. Needs both exchange and queue. See Queue binding |
binding_key | N | routing key | The key of that binding, at most 255 bytes. Left out or empty, it is the routing key the target publishes with, which is the queue name when routing_key is not set |
* = 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.
With both exchange and queue set, messages are published to the exchange, and the queue is declared but bound to the exchange only when bind_queue is true.
Under protocol: "1.0", queue is the address sent to and is required, and exchange, routing_key, bind_queue and binding_key are refused. See Protocol.
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). Under 1.0, 2 sets the message header durable=true and 1 sets durable=false |
mandatory | N | false | Require message to be routed to at least one queue. Refused under 1.0 |
immediate | N | false | Require immediate delivery to consumer (deprecated in RabbitMQ 3.x). Refused under 1.0 |
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 |
disable_retries | N | false | true makes one attempt per message under 0-9-1 (per batch under 1.0) and never waits to retry it, whatever max_retries holds. The payload that attempt fails is still handed back and redelivered by the sender, as any failed send is. Absent or false, nothing changes. In the console this is the |
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) |
Protocol
protocol lets the target send to brokers that speak AMQP 1.0 rather than RabbitMQ's AMQP 0-9-1: ActiveMQ Artemis and Classic, Amazon MQ for ActiveMQ, Solace, and RabbitMQ 4. It applies to the rabbitmq and amqp target types only. A target that sets no protocol sends over AMQP 0-9-1 exactly as before.
protocol | Result |
|---|---|
left out, "" | AMQP 0-9-1, as before |
"0-9-1" | AMQP 0-9-1 |
"1.0", or an unquoted 1.0, which YAML and JSON read as the number 1 | AMQP 1.0 |
| anything else | Configuration error: protocol must be 0-9-1 or 1.0 |
Each key means:
| Key | 0-9-1 | 1.0 |
|---|---|---|
url | As described above | amqp:// or amqps:// only. Its path, if any, is the virtual host (RabbitMQ 4) |
queue | Declared, then published to | The address sent to. Required |
exchange, routing_key, mandatory, immediate, bind_queue, binding_key | As described above | Refused when set, by an error naming the key. An empty string or false counts as unset |
delivery_mode | 2 persistent, 1 not | 2 sets the message header durable=true, 1 sets durable=false |
settlement | Refused when set | See Settlement |
content_type, batch_size, timeout, max_retries, retry_delay, disable_retries, tls.* | As described above | The same meaning |
Under 1.0 each worker opens its own connection and sending link. A lost link is opened again on the next send.
Sign-in
There is no sign-in key under 1.0. The SASL mechanism follows from url and the TLS settings, in this order:
| Configured | SASL mechanism |
|---|---|
A user in url (amqp://user:pass@host) | PLAIN |
No user, and TLS enabled with a client certificate (tls.cert_name / tls.key_name) | EXTERNAL |
| Neither | ANONYMOUS |
The user is never written to logs or stats. The URL is sanitized there.
Settlement
settlement | Result |
|---|---|
left out, "" or at_least_once | Every message waits for the broker's outcome. The payload is acknowledged only when every message is Accepted |
presettled | Fire-and-forget: the broker confirms nothing. Logged as a warning when the target starts |
| anything else | Configuration error |
Under presettled, a message the broker does not take is lost, with nothing logged per message.
Under at_least_once, the broker's outcome decides what happens to the payload:
| Broker outcome | Result |
|---|---|
| Accepted | Delivered and counted |
| Rejected, when every message in the batch that was not accepted was rejected | The records' fault: the payload is retried a capped number of times, then dropped and counted, like any target's rejected record |
Released, Modified, amqp:resource-limit-exceeded, or no outcome at all | Not taken this time: the payload is sent again |
amqp:unauthorized-access, amqp:not-found | The target is broken (credentials or address): the payload is sent again after the target reconnects, and is never dropped |
| The link or connection is lost before the outcome comes | Those messages are re-sent within the same attempt, max_retries times at the most, retry_delay apart |
Delivery is at-least-once: a re-sent payload can duplicate messages the broker had already accepted. The broker's link credit bounds how many messages are in flight.
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.
Under AMQP 0-9-1, 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, and bound to the exchange when bind_queue is true. Under AMQP 1.0, nothing is declared, and each worker has its own connection. See Protocol.
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.
Queue Binding
Under AMQP 0-9-1, a target that sets both exchange and queue publishes to the exchange and declares the queue on every start. The queue receives those messages only when a binding routes them to it.
- With
bind_queue: false, the default, the target leaves the queue's bindings as the broker has them, so the queue has to be bound on the broker. - With
bind_queue: true, the target binds the queue to the exchange right after declaring it, on every start. Binding again is harmless, because the broker keeps a single binding.
The binding carries binding_key and no arguments. What the key does depends on the exchange type:
| Exchange type | Result |
|---|---|
| direct | Routes the messages whose routing key equals binding_key |
| topic | binding_key is a pattern, such as app.#, matched against the routing key |
| fanout | The key is ignored, and every message reaches the queue |
| headers | The key is ignored. The binding has no arguments to match on, so every message reaches the queue |
Left at its default, binding_key is the routing key the target publishes with, so the queue receives what the target sends. Set it when the binding should be wider than that, such as a topic pattern that also matches other routing keys.
The target never creates exchanges, so the exchange must already exist. Binding takes read permission on the exchange and write permission on the queue, on top of the configure permission the queue's declaration needs and the write permission publishing needs. See Which permission or setting is missing?. Turning bind_queue off again does not remove a binding the target made. Remove it on the broker.
Prerequisites
- A running RabbitMQ server, or under
protocol: "1.0"a broker that speaks AMQP 1.0 - 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
Under AMQP 0-9-1, 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. When using both, the queue is bound to the exchange only when bind_queue is true.
Under AMQP 1.0, queue is required and nothing is declared. The address it names must already exist on the broker, unless the broker creates addresses when a link attaches to them.
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"
Exchange with a Bound Queue
Configuration for publishing to an exchange and binding a queue to it, so that the queue receives what the target publishes:
targets:
- name: bound_rabbitmq
type: rabbitmq
properties:
url: "amqp://logger:password@rabbitmq.example.com:5672"
exchange: "logs.topic"
routing_key: "application.logs"
queue: "application_logs"
bind_queue: true
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 whenever queue is set, with or without exchange, and may write to the exchange it publishes through. With queue alone, that exchange is the default exchange and the routing key is the queue name. With bind_queue: true the user also needs read permission on the exchange and write permission on the queue.
| 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, whenever queue is set |
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 bind queue with Exception (403), typically naming ACCESS_REFUSED | Read permission matching the exchange name and write permission matching the queue name | Virtual host, bind_queue: true only |
failed to bind queue with Exception (404), typically naming NOT_FOUND | An exchange that already exists | Virtual host, bind_queue: true only |
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, made on the broker or by bind_queue: true | 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.
With bind_queue: true the user needs read permission on the exchange as well. rabbitmqctl set_permissions -p my_vhost logger ".*" ".*" '^logs\.topic$' adds it for the exchange logs.topic alone.
"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: whenever queue is set, with or without exchange, 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 bind queue"
[Error] [director] [target-<target id>] [bound_rabbitmq] Failed to reinitialize target "bound_rabbitmq" (attempt 2). Reason: failed to bind queue "application_logs" to exchange "logs.topic" with binding key "application.logs": the user may not bind them (binding takes write permission on the queue and read permission on the exchange): Exception (403) Reason: "..."
Cause: bind_queue is true, the queue was declared, and the broker refused to bind it. The message names the queue, the exchange and the binding key, and for the two common replies it says why:
| Text after the binding key | Cause |
|---|---|
the user may not bind them (binding takes write permission on the queue and read permission on the exchange), with Exception (403) | The user lacks read permission on the exchange, write permission on the queue, or both |
the exchange does not exist (the target does not declare exchanges), with Exception (404) | No exchange of that name exists in the virtual host |
Any other reply is logged with the broker's own reason after the binding key.
Fix: for a 403, grant read permission matching the exchange name and write permission matching the queue name, as described under Which permission or setting is missing?. For a 404, create the exchange, or correct exchange. If the permission cannot be granted, set bind_queue: false and have the broker owner bind the queue.
Nothing is sent while this lasts, and the data stays queued.
"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 |
bind_queue binds the queue to the exchange: both exchange and queue must be specified for rabbitmq target | Set both exchange and queue, or remove bind_queue |
binding_key must be at most 255 bytes for rabbitmq target | Shorten binding_key, or remove it to bind with the routing key |
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. Under 0-9-1 this target requires them, so it needs RabbitMQ rather than another AMQP 0-9-1 broker. For a broker that speaks AMQP 1.0, set protocol: "1.0" |
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. Settingqueuebesideexchangedoes not bind the queue by itself: it is declared, and bound only whenbind_queueistrue. Setbind_queue: true, or bind a queue to the exchange on the broker 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.