Skip to content

MQTT

MQTT is a lightweight messaging protocol for small sensors and mobile devices, ideal for IoT and low-bandwidth environments. Upstream docs: https://mqtt.org/

Features

  • QoS Levels: Support for Quality of Service levels 0 (at most once), 1 (at least once), and 2 (exactly once)
  • Retained Messages: Messages can be retained by the broker for new subscribers
  • TLS/SSL Support: Secure connections via the mqtts:// scheme
  • Authentication: Username/password authentication
  • Clean Session: Control whether the broker maintains session state
  • Lazy Initialization: The MQTT client is initialized on the first send, allowing runtime configuration changes before connection

Getting Started

MQTT is widely used in IoT, home automation, and real-time messaging applications. The protocol is supported by many popular brokers:

  • Mosquitto: A popular open-source MQTT broker
  • Home Assistant: Built-in MQTT support for smart home automation
  • EMQX: Enterprise-grade MQTT broker
  • HiveMQ: Scalable MQTT platform

To send notifications via MQTT, you need a running MQTT broker and a topic to publish to. Topics use a hierarchical naming scheme with forward slashes (e.g., home/alerts, sensors/temperature).

URL Formats

The MQTT service supports two URL schemes for connection security:

  • mqtt://: Standard unencrypted connection (port 1883 by default)

mqtt://[username[:password]@]host[:port]/topic

  • mqtts://: TLS-encrypted connection (port 8883 by default)

mqtts://[username[:password]@]host[:port]/topic

URL Fields

  • Username - Auth username Default: empty
    URL part: mqtt://username:password@host:port/topic/
  • Password - Auth password Default: empty
    URL part: mqtt://username:password@host:port/topic/
  • Host - MQTT broker hostname Default: localhost
    URL part: mqtt://username:password@host:port/topic/
  • Port - MQTT broker port Default: 1883
    URL part: mqtt://username:password@host:port/topic/
  • Topic - Target topic name (Required)
    URL part: mqtt://username:password@host:port/topic/

Query/Param Props

Props can be either supplied using the params argument or through the URL using ?key=value&key=value etc.

  • cleansession - Start with a clean session Default: ✔ yes

  • clientid - MQTT client identifier Default: shoutrrr

  • disabletls - Disable TLS encryption Default: ❌ no

  • disabletlsverification - Disable TLS certificate verification Default: ❌ no

  • qos - Quality of Service level (0, 1, or 2) Default: 0 Possible values: AtMostOnce, AtLeastOnce, ExactlyOnce

  • retained - Retain message on broker Default: ❌ no

TLS Configuration Options

The following options control TLS behavior:

  • disabletls: When set to yes, forces an unencrypted connection even if the mqtts:// scheme is used. This overrides the scheme's implicit TLS requirement.

  • disabletlsverification: When set to yes, disables TLS certificate verification while still using encryption. This is useful for self-signed certificates.

Security Warning: Silent TLS Downgrade

Setting disabletls=yes with mqtts:// will force an unencrypted connection despite the secure scheme. This is likely unexpected behavior and can cause silent downgrades where you believe traffic is encrypted but it is not.

Recommendation: If you intentionally want an unencrypted connection, use mqtt:// (non-TLS scheme) instead of combining mqtts:// with disabletls=yes.

When to Use disabletls=yes

This option is intended for specific edge cases, such as:

  • TLS-terminating proxy: When connecting through a proxy that handles TLS termination, where the connection from client-to-proxy uses TLS but proxy-to-broker is plain MQTT. For example, a reverse proxy like Traefik or nginx that terminates TLS and forwards to an internal MQTT broker.
  • Testing environments: Local development where encryption is not required.

Lazy Initialization

The MQTT client uses lazy initialization, meaning the connection to the broker is not established until the first message is sent. This design allows runtime configuration changes to take effect before the connection is created.

How It Works

  1. When you call Initialize(), the service parses the URL and stores the configuration, but does not create the MQTT client
  2. On the first call to Send(), the client is initialized with the current configuration
  3. Once initialized, the client is reused for all subsequent sends

Error Behavior

If the connection attempt during lazy initialization fails, the following behavior applies:

  • The error is returned to the caller immediately
  • The internal client remains uninitialized after a failed attempt
  • Subsequent Send() calls will retry initialization, allowing for transient failure recovery

This retry behavior means that temporary network issues or broker unavailability can be resolved on the next Send() call without requiring a new call to Initialize().

Runtime Configuration

This lazy approach allows you to override connection settings (Host, Port, Username, Password, TLS settings) via params on the first Send() call:

Example Lazy Initialization Runtime Configuration
// Placeholder MQTT URL (will be overridden on first send)
mqttURL := "mqtt://placeholder:1883/topic"

// Create a logger for the service
logger := log.New(os.Stdout, "mqtt: ", log.LstdFlags)

// The message to send
message := "Hello from shoutrrr!"

// Initialize with a placeholder URL
service.Initialize(mqttURL, logger)

// Override connection settings on first send
params := types.Params{
    "host":     "actual-broker.example.com",
    "username": "actual-user",
    "password": "actual-password",
}
service.Send(message, &params)

Note

Configuration changes after the first Send() call will only affect message-related settings (Topic, QoS, Retained), not connection settings. The client connection cannot be reconfigured after initialization.

Examples

Basic Notification

mqtt://broker.example.com/notifications

With Authentication

mqtt://user:[email protected]:1883/home/alerts

Secure Connection

mqtts://user:[email protected]:8883/home/alerts

With QoS and Retained Message

mqtt://broker.example.com/alerts?qos=1&retained=yes

Home Assistant

mqtt://homeassistant.local:1883/homeassistant/notification

Mosquitto broker with custom client ID

mqtt://mosquitto.example.com:1883/sensors/alerts?clientid=shoutrrr-alerts&qos=2

Self-signed Certificate

mqtts://broker.local:8883/secure/alerts?disabletlsverification=yes

Full Configuration

mqtts://admin:[email protected]:8883/production/alerts?clientid=prod-shoutrrr&qos=1&retained=yes&cleansession=no