Why Your Smart Home Routines Break When the Internet Goes Down (And How to Fix Local-Only HA)

My internet went down for six hours last winter, and I expected my Home Assistant setup to shrug it off — that’s the whole point of running it locally, right? Instead, my sunset lighting automation never fired, two of my “smart” plugs stopped responding to motion triggers, and I couldn’t figure out why until I started digging through logs.

That experience is what pushed me to actually build local-only HA automations the right way, not just assume self-hosting automatically means offline-proof. If you’ve had the same surprise, this guide walks through why it happens and how to set up automated smart home routines that keep running with zero internet dependency.

Why Local Automations Break Even When You’re “Self-Hosted”

Running Home Assistant on your own hardware doesn’t automatically mean every automation is internet-independent. Devices that talk to Home Assistant using local protocols like Zigbee, Z-Wave, Matter, Thread, and ESPHome don’t need internet, and automations built on them keep working the same way every day. The problem is almost everyone has automations mixed in that quietly depend on the internet without realizing it. Here are the three real causes.

1. Sun and weather triggers can depend on cloud-polled entities

This one catches people off guard constantly. A sunrise/sunset automation sounds purely local — and the sun integration itself is — but if that automation also checks the state of a device that’s polled through a vendor cloud, the whole automation can silently fail to fire. Real-world reports show exactly this: automations starting at sunrise and sunset that depend on cloud-connected components stop firing after an internet outage, and don’t resume even after the connection comes back, because the trigger is out of sync with the cloud-dependent device state.

2. DNS failures break far more than “cloud stuff”

Home Assistant OS itself needs working DNS for background tasks, and when DNS breaks, the failures look random and unrelated. Home Assistant requires a working DNS server to function, and without one it may be unable to check for and execute updates, show documentation, or reach external services required by add-ons and integrations. This is why some users see integrations fail in clusters that seem to have nothing in common — they all happen to resolve hostnames through the same broken DNS path. One community report described exactly this: a simple time-based automation failing with a DNS timeout while trying to reach a vendor’s cloud API, even though the device could still be controlled manually.

3. Integrations that look local still phone home

Plenty of devices marketed as “local” still routinely check in with a vendor server for cloud sync, firmware checks, or account validation — and if that check-in hangs instead of failing fast, it can stall the automation engine around it. This is different from a device being fully cloud-dependent; it’s a hybrid device that mostly works locally but has a cloud dependency baked in for non-obvious reasons (subscription validation, remote-access tokens, usage analytics).

Where This Shows Up in Real Setups

  • Sunset/sunrise lighting scenes that also reference a cloud-polled smart plug or bulb in the same automation
  • Presence detection using a phone’s GPS through a cloud-based device tracker instead of local network presence (router-based or Bluetooth)
  • Voice control through Alexa or Google Assistant integrations, which route every command through their respective clouds even when controlling local devices
  • Remote access apps that rely on Nabu Casa or port forwarding — these go down, but this is expected and separate from automations breaking
  • Notification-based automations that try to send a push notification via a cloud relay as a step in the automation, and stall waiting on that step

Step-by-Step: Building a True Local-Only Automation Setup

Step 1: Move your device communication to local-only protocols

Replace cloud-dependent integrations with their local equivalents wherever one exists.

  • Zigbee devices: Use ZHA (built into Home Assistant) or Zigbee2MQTT with a USB coordinator like a ConBee II or Sonoff Zigbee dongle, both fully local once paired
  • Z-Wave devices: Use the Z-Wave JS integration with a compatible USB controller
  • Wi-Fi devices: Check whether the manufacturer has a native local API (ESPHome-flashed devices, Shelly’s local mode, Tasmota) instead of relying on the cloud integration
Zigbee devices

Step 2: Identify and replace cloud-only triggers in your existing automations

Go through your automations one at a time and check the trigger and every entity referenced inside conditions and actions — not just the trigger. An automation can have a perfectly local trigger and still fail if a condition checks a cloud-polled entity.

A practical way to audit this:

  1. Open each automation in the UI and switch to YAML mode
  2. Note every entity_id referenced anywhere in the automation
  3. Check each entity’s integration in Settings → Devices & Services — if it shows as a cloud integration (anything requiring an account login, API key, or vendor app), flag it
  4. Replace flagged entities with a local equivalent, or restructure the automation so the cloud-dependent check isn’t a hard gate

Step 3: Switch presence detection to a local method

If you’re using a cloud-based device tracker (most phone-finder apps route through a vendor server), switch to one of these local alternatives:

  • Router-based tracking via your router’s integration, if supported
  • Bluetooth-based presence using ESPHome Bluetooth proxies
  • Local network ping through the built-in Ping integration as a fallback

Step 4: Add a local voice pipeline if you use voice-triggered routines

If any of your routines start with a voice command through Alexa or Google Assistant, those commands travel through that vendor’s cloud before reaching Home Assistant — meaning the routine itself can be fully local, but the trigger isn’t.

The local-only replacement is Home Assistant’s Assist with the Wyoming protocol:

  1. Install a speech-to-text option (Whisper or Speech-to-Phrase) as a local add-on
  2. Install Piper for text-to-speech
  3. Once both apps are running, Home Assistant discovers them under Settings → Devices & Services through the Wyoming integration — add each one, then go to Settings → Voice assistants to create your assistant.
  4. For wake-word detection on satellite devices, add openWakeWord, also via Wyoming

This entire pipeline runs on your local network with no cloud round-trip, so voice-triggered routines keep working during an outage.

Variation: hardware-constrained setups (Raspberry Pi, low-power boards)

If you’re running HA on something modest like a Raspberry Pi, use the smallest viable Whisper model size and keep Piper’s voice model lightweight — both can run on CPU without a GPU, just with slightly higher latency. Don’t run the full Wyoming voice stack and a heavy automation engine load on the same underpowered board if you can avoid it; split voice services onto a separate Raspberry Pi acting as a Wyoming satellite instead.

Advanced Troubleshooting: When Basic Fixes Don’t Solve It

If you’ve already moved to local protocols and audited your automations, but things still break during outages, here are two deeper diagnostic paths.

Advanced Path 1: Fix the underlying DNS dependency, not just the symptom

Because Home Assistant OS requires a working DNS server for core background functionality, a broken or misconfigured DNS setup can produce automation failures that have nothing to do with the automation logic itself. This is especially common if you run a local DNS resolver like AdGuard Home or Pi-hole and recently changed its configuration.

Diagnose it directly:

  1. Check the Settings → System → Repairs page for DNS-related issues; Home Assistant surfaces these explicitly
  2. If you see a DNS server issue, re-enable the fallback DNS option from the CLI as the quickest recovery step
  3. To verify whether your custom DNS resolver is the actual cause, test it directly: run a dig query against your DNS server for _checkdns.home-assistant.io, requesting both A and AAAA records — a correctly behaving DNS server returns NOERROR for both, even with no answer for the AAAA query
  4. If your resolver fails that test, the issue is the resolver’s handling of AAAA (IPv6) queries, not Home Assistant — many lightweight DNS tools mishandle this by timing out instead of returning an empty NOERROR response

This matters for local-only automations because some integrations check connectivity or update status as part of their startup sequence, and a hanging DNS query can delay or block automations that load after them.

Advanced Path 2: Separate “device control” from “device cloud check-in” at the integration level

Some integrations bundle local device control and cloud check-in into a single coordinator that polls on a fixed interval. If the cloud portion times out, the entire coordinator can mark the device unavailable, even though local control still works through a different path.

To diagnose this:

  1. Go to Settings → System → Logs and filter for the integration’s domain name (for example, search for the integration name directly in the log search box)
  2. Look for repeated Error fetching <ip> data or connection timeout messages tied to that integration’s coordinator — this pattern indicates a polling cycle that’s failing in the background even while the device superficially “works”
  3. Check whether the integration has a “local mode” or “local control” toggle in its options (many hybrid integrations do, even if it’s not obvious) and enable it
  4. If no local mode exists, consider replacing the integration entirely with ESPHome (by reflashing the device, if it’s ESP-based) or with Zigbee2MQTT/ZHA if a Zigbee variant of the device exists

This is also where checking home-assistant.log directly (rather than just the UI Logbook) pays off — coordinator-level errors often appear there well before they show up as a visible entity failure in the dashboard.

Tips to Keep Routines Fully Local Going Forward

  • Use a static local IP for your Home Assistant instance so you can always reach it by local address, independent of DNS or remote access working
  • Avoid mixing cloud and local entities inside the same automation — if a routine absolutely needs a cloud entity, isolate it into its own automation so a cloud failure doesn’t take down unrelated local routines
  • Test outages on purpose: unplug your router (not just Wi-Fi) for ten minutes occasionally and watch which automations stop firing — this finds hidden dependencies before a real outage does
  • Keep a local fallback DNS resolver configured even if you normally run AdGuard or Pi-hole, so a misconfiguration in your primary resolver doesn’t take down core HA functions
  • Prefer Zigbee/Z-Wave/Thread/Matter and ESPHome over Wi-Fi cloud devices when buying new hardware — it’s the single biggest lever for staying local-only long-term

FAQ

My automation has a 100% local trigger and 100% local action — why did it still fail during an outage? Check every condition inside the automation, not just the trigger and action. A condition referencing a cloud-polled entity can block the automation from completing even if the trigger and the final action are both local.

Does losing internet affect the Home Assistant app on my phone? Only for remote access. Push notifications and remote access through the Companion App or Nabu Casa cloud service stop working without internet, but if your phone is on the same local network as Home Assistant, the app continues to work normally.

I use AdGuard Home as my DNS resolver and integrations keep timing out — is that related? Yes, this is a known pattern. Test your resolver with a direct dig query against _checkdns.home-assistant.io for A and AAAA records; if it doesn’t return NOERROR for both, your resolver is mishandling IPv6 queries and causing the timeouts.

Can I make Alexa/Google-triggered routines work offline? No — Alexa and Google Assistant route voice commands through their own cloud regardless of where the smart home backend lives. The only fully offline voice option is Home Assistant Assist with a local Wyoming pipeline (Whisper/Piper/openWakeWord).

Will switching everything to Zigbee guarantee zero internet dependency? It removes device-communication dependency, but check the automations themselves too — a Zigbee-triggered automation can still reference a cloud entity somewhere in its conditions, which brings the cloud dependency back in through the side door.


Editor’s Opinion

ok so this one bit me personally, thought my whole setup was bulletproof since it’s “self hosted” and then a six hour outage proved otherwise lol. the sun trigger thing especially annoyed me bc it looked so innocent in the automation editor, no red flags anywhere. anyway going through every entity_id by hand was tedious but honestly kind of satisfying once it was done, like finally actually owning my setup instead of just assuming it worked. worth the afternoon tbh.

Leave a Comment