zeroclaw-labs/zeroclaw · error

use_tls is true but broker_url uses 'mqtt://' (not 'mqtts://

Error message

use_tls is true but broker_url uses 'mqtt://' (not 'mqtts://')

What it means

The MQTT channel encodes transport security twice: in the `broker_url` scheme and in the `use_tls` flag. The validator requires them to agree; `use_tls = true` together with an `mqtt://` URL states 'encrypt this plain connection', which the runtime cannot honor, so the config is rejected before connect.

Source

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

        // QoS validation
        if self.qos > 2 {
            anyhow::bail!("qos must be 0, 1, or 2, got {}", self.qos);
        }

        // Broker URL validation
        let is_tls_scheme = self.broker_url.starts_with("mqtts://");
        let is_mqtt_scheme = self.broker_url.starts_with("mqtt://");

        if !is_tls_scheme && !is_mqtt_scheme {
            anyhow::bail!(
                "broker_url must start with 'mqtt://' or 'mqtts://', got: {}",
                self.broker_url
            );
        }

        // TLS flag validation
        if is_mqtt_scheme && self.use_tls {
            anyhow::bail!("use_tls is true but broker_url uses 'mqtt://' (not 'mqtts://')");
        }

        if is_tls_scheme && !self.use_tls {
            anyhow::bail!(
                "use_tls is false but broker_url uses 'mqtts://' (requires use_tls: true)"
            );
        }

        // Topics validation
        if self.topics.is_empty() {
            anyhow::bail!("at least one topic must be configured");
        }

        // Client ID validation
        if self.client_id.is_empty() {
            validation_bail!(
                RequiredFieldEmpty,
                "client_id",

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. If the broker port is plain (1883), set `use_tls = false`.
  2. If you want TLS, switch the URL to `mqtts://broker.example.com:8883` and keep `use_tls = true`.
  3. Verify the broker's TLS listener port before choosing.

Example fix

# before
broker_url = "mqtt://broker.example.com:1883"
use_tls = true

# after
broker_url = "mqtts://broker.example.com:8883"
use_tls = true
Defensive patterns

Strategy: validation

Validate before calling

let tls_scheme = cfg.broker_url.starts_with("mqtts://");
anyhow::ensure!(
    cfg.use_tls == tls_scheme,
    "use_tls must match the broker_url scheme"
);

Type guard

fn tls_flag_matches(url: &str, use_tls: bool) -> bool {
    use_tls == url.starts_with("mqtts://")
}

Prevention

When it happens

Trigger: `broker_url = "mqtt://broker.example.com:1883"` with `use_tls = true`; flipping `use_tls` on while troubleshooting connectivity but keeping the plain URL.

Common situations: Enabling TLS by toggling only the flag after reading generic MQTT advice; copying a `use_tls = true` snippet onto an existing plain-transport config; brokers that accept TLS on the plain port (TLS via port 1883) — this config shape does not support that.

Related errors


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