zeroclaw-labs/zeroclaw · error

amqp_url must start with 'amqp://' or 'amqps://', got: {}

Error message

amqp_url must start with 'amqp://' or 'amqps://', got: {}

What it means

`AmqpConfig` (the generic AMQP 0-9-1 consumer used for RabbitMQ, Fedora Messaging, etc.) accepts only `amqp://` or `amqps://` as the `amqp_url` scheme, checked as a literal prefix. AMQP 0-9-1 has no other transport scheme, so anything else — including RabbitMQ-specific pseudo-schemes — is rejected before connection.

Source

Thrown at crates/zeroclaw-config/src/schema.rs:16607

    #[serde(default)]
    pub excluded_tools: Vec<String>,
}

impl AmqpConfig {
    /// Validate the AMQP configuration.
    ///
    /// Checks:
    /// - `amqp_url` uses a valid scheme (`amqp://` or `amqps://`)
    /// - `amqps://` connections carry a CA certificate
    /// - `client_cert` and `client_key` are supplied together (mutual TLS)
    /// - the exchange is non-empty
    /// - at least one routing key is bound
    pub fn validate(&self) -> anyhow::Result<()> {
        let is_tls = self.amqp_url.starts_with("amqps://");
        let is_plain = self.amqp_url.starts_with("amqp://");

        if !is_tls && !is_plain {
            anyhow::bail!(
                "amqp_url must start with 'amqp://' or 'amqps://', got: {}",
                self.amqp_url
            );
        }

        if is_tls && self.ca_cert.is_none() {
            anyhow::bail!("amqps:// requires ca_cert to verify the broker");
        }

        match (self.client_cert.is_some(), self.client_key.is_some()) {
            (true, false) => {
                anyhow::bail!(
                    "client_cert is set but client_key is missing (both are required for mutual TLS)"
                )
            }
            (false, true) => {
                anyhow::bail!(
                    "client_key is set but client_cert is missing (both are required for mutual TLS)"

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Use `amqp://host:5672/<vhost>` for plain connections (URL-encode the default vhost `/` as `%2F`).
  2. Use `amqps://host:5671/<vhost>` for TLS and supply `ca_cert` (and client pair for mTLS).
  3. Verify you are pointing at the AMQP port, not the management port.

Example fix

# before
amqp_url = "rabbitmq://localhost:5672/%2F"

# after
amqp_url = "amqp://localhost:5672/%2F"
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(
    cfg.amqp_url.starts_with("amqp://") || cfg.amqp_url.starts_with("amqps://"),
    "bad amqp_url scheme: {}",
    cfg.amqp_url
);

Type guard

fn is_amqp_url(url: &str) -> bool {
    url.starts_with("amqp://") || url.starts_with("amqps://")
}

Prevention

When it happens

Trigger: `amqp_url = "rabbitmq://localhost:5672/%2F"` (Spring-style pseudo-scheme); a bare `localhost:5672`; pasting an `http://` management-UI URL instead of the AMQP port; typos like `amqp:/`.

Common situations: Copying connection strings from Spring Boot or Heroku docs that use `rabbitmq://`; grabbing the URL from the RabbitMQ management interface (15672, HTTP) rather than the AMQP listener (5672/5671); missing vhost encoding is fine but a missing scheme is not.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/84c45560f6500fdb. Report an issue: GitHub.