{"record":{"id":"999eee224a862c3c","repo":"zeroclaw-labs/zeroclaw","slug":"broker-url-must-start-with-mqtt-or-mqtts","errorCode":null,"errorMessage":"broker_url must start with 'mqtt://' or 'mqtts://', got: {}","messagePattern":"broker_url must start with 'mqtt://' or 'mqtts://', got: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":16263,"sourceCode":"    ///\n    /// Checks:\n    /// - QoS is 0, 1, or 2\n    /// - broker_url uses valid scheme (`mqtt://` or `mqtts://`)\n    /// - `use_tls` flag matches broker_url scheme\n    /// - At least one topic is configured\n    /// - client_id is non-empty\n    pub fn validate(&self) -> anyhow::Result<()> {\n        // QoS validation\n        if self.qos > 2 {\n            anyhow::bail!(\"qos must be 0, 1, or 2, got {}\", self.qos);\n        }\n\n        // Broker URL validation\n        let is_tls_scheme = self.broker_url.starts_with(\"mqtts://\");\n        let is_mqtt_scheme = self.broker_url.starts_with(\"mqtt://\");\n\n        if !is_tls_scheme && !is_mqtt_scheme {\n            anyhow::bail!(\n                \"broker_url must start with 'mqtt://' or 'mqtts://', got: {}\",\n                self.broker_url\n            );\n        }\n\n        // TLS flag validation\n        if is_mqtt_scheme && self.use_tls {\n            anyhow::bail!(\"use_tls is true but broker_url uses 'mqtt://' (not 'mqtts://')\");\n        }\n\n        if is_tls_scheme && !self.use_tls {\n            anyhow::bail!(\n                \"use_tls is false but broker_url uses 'mqtts://' (requires use_tls: true)\"\n            );\n        }\n\n        // Topics validation\n        if self.topics.is_empty() {","sourceCodeStart":16245,"sourceCodeEnd":16281,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L16245-L16281","documentation":"`MqttConfig::validate` accepts only `mqtt://` (plain) and `mqtts://` (TLS) broker URLs, checked as a literal prefix of `broker_url`. Any other scheme — or no scheme at all — is rejected before connection because the listener cannot infer the transport.","triggerScenarios":"`broker_url = \"tcp://localhost:1883\"` (the scheme many mosquitto tools use), `broker_url = \"localhost:1883\"`, `http://`/`https://` prefixes, or a pasted URL with a typo like `mqtt:/`.","commonSituations":"Copying a `tcp://` URI from mosquitto/mqtt.js documentation; pasting a bare host:port from an infrastructure note; switching from another MQTT client library whose examples use different schemes.","solutions":["Change the scheme to `mqtt://` for plain connections (e.g. `mqtt://localhost:1883`).","Use `mqtts://host:8883` for TLS and remember to set `use_tls = true` to match.","Double-check the pasted URL has no typos or missing slashes."],"exampleFix":"# before\nbroker_url = \"tcp://localhost:1883\"\n\n# after\nbroker_url = \"mqtt://localhost:1883\"","handlingStrategy":"validation","validationCode":"anyhow::ensure!(\n    cfg.broker_url.starts_with(\"mqtt://\") || cfg.broker_url.starts_with(\"mqtts://\"),\n    \"bad broker_url scheme: {}\",\n    cfg.broker_url\n);","typeGuard":"fn is_mqtt_url(url: &str) -> bool {\n    url.starts_with(\"mqtt://\") || url.starts_with(\"mqtts://\")\n}","tryCatchPattern":null,"preventionTips":["Convert tcp:// URIs from mosquitto tooling to mqtt:// before pasting.","Always include the scheme and port in broker URLs.","Let validation run at config load, not at first connect."],"tags":["mqtt","config","url","scheme","zeroclaw"],"backgroundTag":"invalid-url-scheme","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}