Introduction
There’s nothing more frustrating than waking up to find your smart home automations completely dead — lights not responding, sensors showing “unavailable,” and your carefully crafted routines doing absolutely nothing. You check the logs, and there it is: the MQTT broker restarted overnight, and now half your automations are broken.
I’ve been there. More than once, actually. The first time it happened, I spent almost three hours trying to figure out what went wrong. My Zigbee2MQTT devices were offline, my climate automations stopped working, and my motion-triggered lights acted like they didn’t exist anymore.
If you’re reading this, chances are you’re dealing with the same headache right now. The good news? This is a well-known problem, and once you understand why it happens, fixing it becomes straightforward. In this guide, I’ll walk you through every step I’ve learned — from diagnosing the root cause to building automations that survive broker restarts without breaking a sweat.
Let’s fix this once and for all.
[📷 Image Placeholder: Screenshot showing Home Assistant dashboard with multiple entities displaying “unavailable” status after an MQTT broker restart]
Alt text: Home Assistant dashboard showing unavailable MQTT entities after broker restart
Why Do Home Assistant Automations Break After MQTT Broker Restarts?
Before jumping into solutions, let’s understand what actually happens under the hood when your MQTT broker restarts.
The Connection Lifecycle Problem
When your MQTT broker (usually Mosquitto) restarts, every connected client — including Home Assistant, Zigbee2MQTT, Tasmota devices, and ESPHome nodes — loses its connection. Here’s what happens in sequence:
- Broker shuts down → All active connections drop immediately
- Clients detect disconnection → Some detect it quickly, others take time depending on keep-alive settings
- Broker comes back online → It starts fresh with no memory of previous sessions (unless persistence is enabled)
- Clients attempt reconnection → Each client reconnects at its own pace
- Subscriptions are re-established → Topics need to be re-subscribed
- Retained messages are delivered → But only if they were set as retained before the restart
The problem? Home Assistant’s MQTT integration might reconnect before your devices do, or it might miss critical state updates during the gap. Your automations then trigger (or fail to trigger) based on stale or missing data.
Retained Messages vs. Non-Retained Messages
This is where most people get confused. If your devices publish their state without the retain flag, then after a broker restart:
- Home Assistant reconnects and subscribes to topics
- But there’s no retained message waiting on those topics
- So entities show as “unavailable” until the device publishes again
- Automations depending on those entities either fail or behave unpredictably
[📷 Image Placeholder: Diagram showing MQTT message flow between devices, broker, and Home Assistant during a restart event]
Alt text: MQTT message flow diagram showing what happens during broker restart and reconnection
Step 1: Check Your MQTT Broker Logs First
The very first thing you should do is examine what actually happened during the restart.
For Mosquitto (Most Common Broker)
Open your Mosquitto log file:
Bashsudo cat /var/log/mosquitto/mosquitto.log
Or if you’re running Mosquitto as a Home Assistant add-on:
Bashha addons logs core_mosquitto
Look for entries like:
text1717890234: mosquitto version 2.0.18 starting
1717890234: Config loaded from /etc/mosquitto/mosquitto.conf
1717890234: Opening ipv4 listen socket on port 1883
1717890234: Client home-assistant reconnected (clean session)
1717890234: Client zigbee2mqtt reconnected (clean session)
What to Look For
| Log Entry | What It Means |
|---|---|
clean session = true | Client reconnected and all previous subscriptions were cleared |
clean session = false | Client reconnected and broker restored previous subscriptions |
Socket error on client | A client didn’t disconnect cleanly |
Client disconnected due to protocol error | Version mismatch or configuration issue |
Pro tip: If you see
clean session = truefor Home Assistant, that’s likely your primary problem. It means HA is starting fresh every time instead of resuming its previous session.
Step 2: Verify Home Assistant’s MQTT Integration Status
After checking broker logs, look at what Home Assistant itself reports.
Check Home Assistant Logs
Navigate to Settings → System → Logs and filter for mqtt. You’re looking for messages like:
textWARNING: MQTT connection lost; reconnecting...
INFO: MQTT connected successfully
ERROR: Entity sensor.living_room_temperature is unavailable
Use Developer Tools to Inspect Entity States
Go to Developer Tools → States and search for your MQTT entities. Check these things:
- Is the state
unavailableorunknown? - When was the
last_changedtimestamp? - Does the entity have the expected attributes?
YAML# Example of what a healthy MQTT entity looks like
state: 'on'
attributes:
friendly_name: Living Room Motion
device_class: motion
last_changed: '2024-12-15T08:23:45.123456+00:00'
last_updated: '2024-12-15T08:23:45.123456+00:00'
If last_changed shows a timestamp from before the broker restart and the state is unavailable, the entity never recovered.
[📷 Image Placeholder: Screenshot of Home Assistant Developer Tools States panel showing MQTT entity details]
Alt text: Home Assistant Developer Tools showing MQTT entity state inspection after broker restart
Step 3: Enable MQTT Broker Persistence
This is arguably the single most impactful fix you can make. Persistence tells Mosquitto to save messages to disk so they survive restarts.
Configure Mosquitto Persistence
Edit your Mosquitto configuration file:
Bashsudo nano /etc/mosquitto/mosquitto.conf
Add or modify these lines:
conf# Enable persistence
persistence true
persistence_location /var/lib/mosquitto/
# Save persistent data every 30 minutes (or on clean shutdown)
autosave_interval 1800
autosave_on_changes true
# Keep retained messages across restarts
retained_persistence true
Then restart Mosquitto:
Bashsudo systemctl restart mosquitto
For Home Assistant Mosquitto Add-on
If you’re using the official add-on, persistence is usually enabled by default. But verify by checking the add-on configuration. You can also look at the data directory:
text/data/mosquitto/
What Persistence Actually Saves
- Retained messages on all topics
- In-flight QoS 1 and QoS 2 messages that haven’t been acknowledged
- Client subscriptions for clients using
clean_session = false
Important: Persistence does not save non-retained messages that were published before the restart. If a device published its state without the retain flag, that message is gone.
Step 4: Fix the Retain Flag on Your Devices
This is where many smart home setups fall apart. Your devices need to publish their states with retain: true so that after a broker restart, the last known state is immediately available.
Zigbee2MQTT Configuration
In your Zigbee2MQTT configuration.yaml:
YAMLmqtt:
base_topic: zigbee2mqtt
server: mqtt://localhost:1883
# These are critical for surviving broker restarts
force_disable_retain: false
advanced:
# Ensure availability messages are retained
availability_timeout: 0
last_seen: 'ISO_8601'
availability:
active:
timeout: 10
passive:
timeout: 1500
Tasmota Devices
For Tasmota devices, the retain flag is controlled by the SensorRetain and StateRetain commands:
text# In Tasmota console
SensorRetain 1
StateRetain 1
This tells Tasmota to publish sensor and state data with the retain flag.
ESPHome Devices
For ESPHome, MQTT retain is configured per component:
YAMLmqtt:
broker: 192.168.1.100
discovery_retain: true
sensor:
- platform: dht
pin: D2
temperature:
name: "Room Temperature"
retain: true
humidity:
name: "Room Humidity"
retain: true
binary_sensor:
- platform: gpio
pin: D3
name: "Door Sensor"
retain: true
[📷 Image Placeholder: Screenshot showing Zigbee2MQTT configuration file with retain settings highlighted]
Alt text: Zigbee2MQTT configuration file showing proper retain flag settings for MQTT broker restart resilience
Step 5: Configure MQTT Quality of Service (QoS) Properly
QoS levels determine how reliably messages are delivered. For automations that must survive broker restarts, QoS matters a lot.
QoS Levels Explained
| QoS Level | Name | Behavior | Best For |
|---|---|---|---|
| 0 | At most once | Fire and forget, no acknowledgment | Non-critical sensors (temperature) |
| 1 | At least once | Message is delivered at least once, may duplicate | Most automations |
| 2 | Exactly once | Message is delivered exactly once | Critical operations (locks, alarms) |
Set QoS in Home Assistant MQTT Configuration
In your Home Assistant configuration.yaml:
YAMLmqtt:
sensor:
- name: "Living Room Temperature"
state_topic: "zigbee2mqtt/living_room_sensor"
value_template: "{{ value_json.temperature }}"
qos: 1
binary_sensor:
- name: "Front Door"
state_topic: "zigbee2mqtt/front_door_sensor"
value_template: "{{ value_json.contact }}"
qos: 1
My Recommendation
For most home automation use cases, QoS 1 is the sweet spot. QoS 2 adds significant overhead and is rarely necessary. QoS 0 is fine for frequently updating sensors where missing one update doesn’t matter.
Step 6: Build Restart-Resilient Automations
Now let’s get into the actual automation code. Here’s how to write automations that gracefully handle broker restarts.
Pattern 1: Add an MQTT Reconnection Trigger
Create an automation that explicitly runs when MQTT reconnects:
YAMLautomation:
- id: 'mqtt_reconnect_handler'
alias: 'Handle MQTT Broker Reconnection'
description: 'Re-sync states and restart dependent automations after MQTT reconnects'
trigger:
- platform: event
event_type: mqtt_connected
action:
- delay:
seconds: 10 # Give devices time to reconnect
- service: mqtt.publish
data:
topic: "zigbee2mqtt/bridge/request/health_check"
payload: ""
- service: homeassistant.update_entity
target:
entity_id:
- sensor.living_room_temperature
- binary_sensor.front_door
- sensor.humidity_bathroom
- service: notify.mobile_app
data:
title: "MQTT Reconnected"
message: "Broker reconnected at {{ now().strftime('%H:%M') }}. Re-syncing devices."
Pattern 2: Wait for Entity Availability Before Running
YAMLautomation:
- id: 'motion_light_resilient'
alias: 'Motion Activated Light (Restart Safe)'
trigger:
- platform: state
entity_id: binary_sensor.hallway_motion
to: 'on'
condition:
- condition: not
conditions:
- condition: state
entity_id: binary_sensor.hallway_motion
state: 'unavailable'
- condition: not
conditions:
- condition: state
entity_id: light.hallway
state: 'unavailable'
action:
- service: light.turn_on
target:
entity_id: light.hallway
data:
brightness: 255
transition: 2
Pattern 3: Auto-Recovery Automation
This automation detects when MQTT entities go unavailable and attempts to recover them:
YAMLautomation:
- id: 'mqtt_entity_recovery'
alias: 'MQTT Entity Auto-Recovery'
trigger:
- platform: state
entity_id:
- sensor.living_room_temperature
- binary_sensor.front_door
- sensor.humidity_bathroom
to: 'unavailable'
for:
minutes: 2
action:
- service: mqtt.reload
- delay:
seconds: 15
- if:
- condition: state
entity_id: "{{ trigger.entity_id }}"
state: 'unavailable'
then:
- service: notify.mobile_app
data:
title: "⚠️ MQTT Device Still Offline"
message: "{{ trigger.to_state.attributes.friendly_name }} has been unavailable for over 2 minutes after recovery attempt."
[📷 Image Placeholder: Screenshot of Home Assistant automation editor showing the MQTT reconnection handler automation]
Alt text: Home Assistant automation editor with MQTT reconnection handler automation configuration
Step 7: Monitor MQTT Broker Health Proactively
Don’t wait for things to break. Set up monitoring so you know when the broker restarts and can verify everything recovered properly.
Create an MQTT Uptime Sensor
YAMLmqtt:
sensor:
- name: "MQTT Broker Uptime"
state_topic: "$SYS/broker/uptime"
unit_of_measurement: "seconds"
icon: mdi:clock-outline
- name: "MQTT Connected Clients"
state_topic: "$SYS/broker/clients/connected"
icon: mdi:devices
- name: "MQTT Messages Received"
state_topic: "$SYS/broker/messages/received"
icon: mdi:email-receive
Note: The
$SYStopics are built into Mosquitto and provide real-time broker statistics. You need to enable them in your Mosquitto config withsys_interval 10.
Create a Broker Health Dashboard Card
YAMLtype: entities
title: MQTT Broker Health
entities:
- entity: sensor.mqtt_broker_uptime
name: Broker Uptime
- entity: sensor.mqtt_connected_clients
name: Connected Clients
- entity: sensor.mqtt_messages_received
name: Messages Received
Alert on Broker Restart
YAMLautomation:
- id: 'mqtt_broker_restart_alert'
alias: 'Alert on MQTT Broker Restart'
trigger:
- platform: numeric_state
entity_id: sensor.mqtt_broker_uptime
below: 60 # Uptime less than 60 seconds means it just restarted
action:
- service: notify.mobile_app
data:
title: "🔄 MQTT Broker Restarted"
message: "The MQTT broker was restarted. Current uptime: {{ states('sensor.mqtt_broker_uptime') }} seconds. Monitoring for device recovery."
data:
priority: high
Step 8: Use the MQTT Birth and Last Will Messages
Birth and Last Will and Testament (LWT) messages are powerful MQTT features that help you track client connectivity.
How Birth and LWT Messages Work
| Message Type | When It’s Sent | Purpose |
|---|---|---|
| Birth | When a client connects/reconnects | Announces “I’m online” |
| LWT | When a client disconnects unexpectedly | Announces “I’m offline” |
Configure Home Assistant’s Birth and Will Messages
In configuration.yaml:
YAMLmqtt:
birth_message:
topic: "homeassistant/status"
payload: "online"
qos: 1
retain: true
will_message:
topic: "homeassistant/status"
payload: "offline"
qos: 1
retain: true
Configure Zigbee2MQTT’s Availability
Zigbee2MQTT uses similar concepts. In its configuration.yaml:
YAMLavailability:
active:
timeout: 10
passive:
timeout: 1500
advanced:
availability_blocklist: []
availability_passlist: []
This ensures that after a broker restart, devices correctly report their availability status.
[📷 Image Placeholder: Diagram showing Birth and LWT message flow between Home Assistant, MQTT broker, and IoT devices]
Alt text: MQTT Birth and Last Will Testament message flow diagram for Home Assistant device availability tracking
Step 9: Debug with MQTT Explorer (Real-Time)
When troubleshooting, you need to see exactly what’s happening on your MQTT broker in real time. MQTT Explorer is the best tool for this.
What to Check in MQTT Explorer After a Broker Restart
- Connect to your broker using the same credentials as Home Assistant
- Check the topic tree — Are your device topics populated?
- Look for retained messages — They should have a small flag icon
- Check
homeassistant/status— Should show “online” - Check
zigbee2mqtt/bridge/state— Should show “online” - Monitor message flow — Are devices publishing updates?
Common Issues You’ll Spot
- Empty topics: Device reconnected but hasn’t published yet
- Stale retained messages: Old data from before the restart
- Missing topics: Device failed to reconnect entirely
- Duplicate topics: Naming conflicts after restart
[📷 Image Placeholder: Screenshot of MQTT Explorer showing the topic tree with retained messages after a broker restart]
Alt text: MQTT Explorer interface showing topic tree with retained messages and device connectivity status
Step 10: Implement a Proper Restart Strategy
Sometimes the issue isn’t the restart itself — it’s how you’re restarting.
The Wrong Way to Restart Mosquitto
Bash# DON'T do this
sudo kill -9 $(pidof mosquitto)
Killing the process with SIGKILL prevents Mosquitto from:
- Saving persistent data to disk
- Sending LWT messages for connected clients
- Cleanly closing client connections
The Right Way to Restart Mosquitto
Bash# DO this instead
sudo systemctl restart mosquitto
Or if you need a graceful stop:
Bashsudo systemctl stop mosquitto
sleep 5
sudo systemctl start mosquitto
Restart Order Matters
If you need to restart multiple components, follow this order:
- Stop Home Assistant automations (disable critical ones)
- Restart Mosquitto broker
- Wait 10-15 seconds for the broker to fully initialize
- Restart Zigbee2MQTT / other bridges
- Wait for devices to reconnect (check MQTT Explorer)
- Restart Home Assistant MQTT integration (or reload)
- Re-enable automations
YAML# You can create a script for this
script:
safe_mqtt_restart:
alias: "Safe MQTT Restart Sequence"
sequence:
- service: automation.turn_off
target:
entity_id: group.critical_automations
- delay:
seconds: 5
- service: hassio.addon_restart
data:
addon: core_mosquitto
- delay:
seconds: 15
- service: mqtt.reload
- delay:
seconds: 10
- service: automation.turn_on
target:
entity_id: group.critical_automations
- service: notify.mobile_app
data:
message: "MQTT restart sequence completed successfully."
Real-World Scenario: My Complete Debugging Story
Let me share exactly what happened to me and how I fixed it, step by step.
The Problem
I run a fairly complex Home Assistant setup with:
- 23 Zigbee devices via Zigbee2MQTT
- 8 Tasmota smart plugs
- 4 ESPHome sensors
- Mosquitto broker running as an HA add-on
One morning, my wife complained that the bathroom fan didn’t turn on automatically with the humidity sensor. The kitchen lights didn’t respond to motion. The thermostat automation was stuck.
The Investigation
Step 1: Checked HA logs → Found mqtt_connected event at 3:47 AM (unplanned broker restart)
Step 2: Checked Mosquitto logs → The add-on auto-updated overnight and restarted
Step 3: Checked entity states → 15 out of 35 MQTT entities showed “unavailable”
Step 4: Opened MQTT Explorer → Many topics had no retained messages
The Root Causes (Multiple Issues)
- Zigbee2MQTT was configured with
force_disable_retain: true(I had set this months ago while testing and forgot) - Tasmota devices didn’t have
StateRetainenabled - My automations had no availability checks — they just failed silently
- No reconnection handler existed to re-sync states
The Fix
I applied every technique described in this article:
- Enabled persistence on Mosquitto ✅
- Fixed retain flags on all devices ✅
- Added
mqtt_connectedevent handler ✅ - Added availability conditions to all critical automations ✅
- Set up broker health monitoring ✅
- Created the safe restart script ✅
The Result
Since implementing these changes four months ago, my broker has restarted six times (updates, power outages, testing). Every single time, all automations recovered within 30 seconds without manual intervention.
[📷 Image Placeholder: Before and after screenshot comparison showing entity states — unavailable vs. properly recovered]
Alt text: Before and after comparison of Home Assistant entity states showing successful MQTT recovery after implementing fixes
Advanced: Custom MQTT Watchdog Script
For those who want an extra layer of protection, here’s a custom watchdog automation that continuously monitors MQTT health:
YAMLautomation:
- id: 'mqtt_watchdog'
alias: 'MQTT Watchdog - Continuous Health Check'
trigger:
- platform: time_pattern
minutes: "/5" # Check every 5 minutes
action:
- service: mqtt.publish
data:
topic: "homeassistant/watchdog/ping"
payload: "{{ now().isoformat() }}"
qos: 1
- delay:
seconds: 5
- if:
- condition: template
value_template: >
{{ (as_timestamp(now()) - as_timestamp(states('sensor.mqtt_watchdog_pong'))) > 30 }}
then:
- service: notify.mobile_app
data:
title: "🚨 MQTT Health Check Failed"
message: "MQTT watchdog didn't receive pong response. Broker may be unresponsive."
data:
priority: high
mqtt:
sensor:
- name: "MQTT Watchdog Pong"
state_topic: "homeassistant/watchdog/ping"
Common Mistakes to Avoid
Here’s a quick checklist of things that will make your broker restart problems worse:
❌ Don’t Do This
- Don’t use QoS 0 for critical automations — messages will be lost during restarts
- Don’t disable persistence to “save SD card writes” — use an SSD instead
- Don’t set very short keep-alive intervals — it causes unnecessary reconnection churn
- Don’t ignore
unavailablestates in automations — always check availability - Don’t run Mosquitto and Home Assistant on different restart schedules without a reconnection handler
✅ Do This Instead
- Use QoS 1 for all important entities
- Enable persistence with reasonable autosave intervals
- Set keep-alive to 60 seconds (default is fine)
- Always add availability conditions to automations
- Create a reconnection handler automation
- Monitor broker health proactively
Frequently Asked Questions (FAQ)
Why do my MQTT entities show “unavailable” after a broker restart?
When the MQTT broker restarts, the connection between Home Assistant and the broker is dropped. If the device topics don’t have retained messages, Home Assistant has no way to know the current state of those entities until the devices reconnect and publish new state updates. Enable retain flags on your devices and enable broker persistence to fix this.
How long should I wait after a broker restart for all devices to reconnect?
It depends on the device type. Zigbee devices via Zigbee2MQTT typically reconnect within 5-10 seconds. WiFi devices like Tasmota or ESPHome take 10-30 seconds depending on your network. Battery-powered Zigbee sensors may take several minutes because they only communicate periodically. I recommend building a 30-second delay into your reconnection handler.
Can I prevent MQTT broker restarts entirely?
You can minimize them but not prevent them entirely. Broker updates, system reboots, power outages, and memory issues can all cause restarts. The better approach is to make your system resilient to restarts rather than trying to prevent them. Use persistence, retained messages, and reconnection handlers.
Does changing QoS level affect performance?
QoS 1 adds minimal overhead compared to QoS 0 — typically a few extra bytes per message for the acknowledgment. QoS 2 adds significantly more overhead because it requires a four-step handshake. For home automation with dozens of devices, QoS 1 has no noticeable performance impact.
Should I use clean_session: false for Home Assistant?
In MQTT v3.1.1, setting clean_session: false tells the broker to remember subscriptions and queue messages for the client while it’s disconnected. However, Home Assistant’s MQTT integration handles reconnection well on its own, and using persistent sessions can sometimes cause issues with stale queued messages. For most users, the default settings are fine — focus on retained messages and persistence instead.
How do I know if my Mosquitto persistence is working?
Check if the persistence file exists and is being updated:
Bashls -la /var/lib/mosquitto/mosquitto.db
The file should exist and its modification timestamp should be recent. You can also check the Mosquitto log for lines like:
textSaving in-memory database to /var/lib/mosquitto/mosquitto.db
Will this fix battery-powered Zigbee sensors too?
Battery-powered sensors are trickier because they sleep most of the time and only wake up to send data. They won’t reconnect immediately after a broker restart. The retained message strategy helps here because the last known state will be available from the retained message, even if the sensor hasn’t woken up yet. Combined with Zigbee2MQTT’s passive availability timeout, this gives you the best coverage.
Can I use this approach with other MQTT brokers like EMQX or HiveMQ?
Yes! The concepts of persistence, retained messages, QoS, and Birth/LWT messages are part of the MQTT standard and work with any compliant broker. The configuration syntax will differ, but the principles are identical. Check your broker’s documentation for specific configuration options.
Useful External Resources
- Home Assistant MQTT Integration Documentation
- Mosquitto MQTT Broker Configuration Guide
- Zigbee2MQTT MQTT Configuration
- MQTT Explorer Download
- Tasmota MQTT Settings Documentation
- Understanding MQTT QoS Levels — HiveMQ
Final Thoughts
Debugging MQTT broker restart issues in Home Assistant isn’t about finding one magic fix — it’s about building a resilient system from multiple layers of protection. Retained messages, broker persistence, QoS settings, availability conditions, reconnection handlers, and proactive monitoring all work together to create a smart home that recovers automatically.
The time you invest now in setting this up properly will save you countless hours of frustration later. And more importantly, your family won’t wake up to a broken smart home ever again.
If this guide helped you, bookmark it. You’ll probably need to reference it again when you add new devices or change your MQTT setup. Good luck, and happy automating!