home-assistant / home-assistant/supervisor
HA Supervisor periodically reports host_internet: false and blocks addon/supervisor updates, but the host has full internet connectivity. Only fix is ha supervisor restart.
- Dominant language
- Python
- Stars
- 2.2k
- Forks
- 807
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 55
Description
### Describe the issue you are experiencing
## Symptom
HA Supervisor periodically reports host_internet: false and blocks addon/supervisor
updates ('AddonManager.update' blocked from execution, no host internet connection).
The host has full internet connectivity throughout — integrations keep working.
Only fix is ha supervisor restart.
Observed in Supervisor 12.6.1 on HA OS (Alpine 3.23.3), Proxmox VM, macmini1.
# update May 2,2026
Additional symptom: AppArmor update abort
The dead D-Bus socket also manifests as a hard update block with a misleading AppArmor error:
ERROR [supervisor.host.apparmor] Can't load profile hassio-supervisor: [Errno 9] Bad file descriptor
ERROR [supervisor.supervisor] Can't update AppArmor profile!
CRITICAL [supervisor.supervisor] Abort update because of an issue with AppArmor: Can't update AppArmor profile!
The [Errno 9] Bad file descriptor is the same dead D-Bus socket — not an actual AppArmor problem. The supervisor fetches the new profile successfully from , then tries to load it via the AppArmor D-Bus interface, hits the dead fd, and aborts the entire update.
In the logs I captured, the connectivity D-Bus error appeared at 10:47 and the AppArmor abort happened at 11:22 — the socket had been dead ~35 minutes before an update was attempted.
Same fix: ha supervisor restart resolves both symptoms.
Worth calling out because “Can’t update AppArmor profile” sends users down an AppArmor/kernel troubleshooting path when the real issue is the D-Bus reconnection bug.
## Root Cause
The Supervisor conflates a broken D-Bus connection with an actual internet outage.
Full failure chain:
1. Something causes the dbus_fast MessageBus socket to go dead (EOF — likely a
transient NM event: DHCP renew, Docker network churn, VM NIC reset).
2. NetworkManager fires a burst of properties_changed D-Bus signals at the same time.
3. DBus.sync_property_changes callback fires (supervisor/utils/dbus.py:261).
It calls update(changed) → NetworkInterface.update() (dbus/network/interface.py:167)
→ self.connection.connect(self.connected_dbus.bus) → DBus.connect() → init_proxy()
→ introspect().
4. introspect() retries 3× catching EOFError (bus is dead), then raises:
DBusFatalError: Could not get introspection data after 3 attempts
5. sync_property_change has no try/except, so the exception becomes an unhandled
asyncio task — logged as "Task exception was never retrieved". The burst means
this fires 30+ times simultaneously (Task-80999851 through ~880).
6. All subsequent D-Bus calls on the dead bus fail with [Errno 9] Bad file descriptor.
7. check_connectivity() in supervisor/host/network.py catches DBusError and sets
self.connectivity = False. This runs on every periodic check, always fails, always
returns False. The Supervisor never recovers.
The bug is that step 7 equates a D-Bus connection error with "no internet":
```
# supervisor/host/network.py ~line 152
except DBusError as err:
_LOGGER.warning("Can't update connectivity information: %s", err)
self.connectivity = False # ← WRONG: this is a D-Bus error, not an internet outage
```
## Proposed Fix (two files)
### Fix 1 — supervisor/utils/dbus.py around line 279
Catch DBusFatalError in sync_property_change so it doesn't leak as an unhandled
task exception. The periodic refresh will pick up any missed property changes.
```
async def sync_property_change(
prop_interface: str, changed: dict[str, Any], invalidated: list[str]
) -> None:
"""Sync property changes to cache."""
if interface != prop_interface:
return
_LOGGER.debug(
"Property change for %s-%s: %s changed & %s invalidated",
self.bus_name,
self.object_path,
list(changed.keys()),
invalidated,
)
try:
if invalidated:
await update()
else:
await update(changed)
except DBusFatalError as err:
_LOGGER.warning(
"D-Bus property change sync failed for %s-%s: %s",
self.bus_name,
self.object_path,
err,
)
```
### Fix 2 — supervisor/host/network.py around line 152 (the important one)
Use None (unknown) instead of False (definitely no internet) when the failure
is a D-Bus connection error, not an NM connectivity report:
```
except DBusError as err:
_LOGGER.warning("Can't update connectivity information: %s", err)
# A D-Bus error means we *can't check* connectivity — not that it's gone.
# Setting False permanently blocks addon updates on a false-negative.
# None (unknown) lets the Supervisor retry without blocking operations.
self.connectivity = None
```
None is already used in this codebase to mean "connectivity checking disabled/unknown"
(see the connectivity_enabled branch above this block). Downstream job checks treat
None differently from False — they don't block on unknown state.
### What type of installation are you running?
Home Assistant OS
### Which operating system are you running on?
Debian
### Steps to reproduce the issue
1. Have a blip on the hosts network
2. Host_internet goes to false
3. Never recovers. A reboot of the VM sometimes works, a full reboot of the host always works
### Anything in the Supervisor logs that might be useful for us?
```txt
None really relevant. The reasons behind the host_internet: false are varied.
```
### System information
## System Information
version | core-2026.4.3
-- | --
installation_type | Home Assistant OS
dev | false
hassio | true
docker | true
container_arch | amd64
user | root
virtualenv | false
python_version | 3.14.2
os_name | Linux
os_version | 6.12.77-haos
arch | x86_64
timezone | America/Edmonton
config_dir | /config
Home Assistant Community Store
GitHub API | ok
-- | --
GitHub Content | ok
GitHub Web | ok
HACS Data | ok
GitHub API Calls Remaining | 5000
Installed Version | 2.0.5
Stage | running
Available Repositories | 2936
Downloaded Repositories | 13
Home Assistant Cloud
logged_in | false
-- | --
can_reach_cert_server | ok
can_reach_cloud_auth | ok
can_reach_cloud | ok
Home Assistant Supervisor
host_os | Home Assistant OS 17.2
-- | --
update_channel | stable
supervisor_version | supervisor-2026.04.0
agent_version | 1.8.1
docker_version | 29.3.1
disk_total | 30.8 GB
disk_used | 14.8 GB
nameservers | 192.168.3.1
healthy | true
supported | true
host_connectivity | true
supervisor_connectivity | true
ntp_synchronized | true
virtualization | kvm
board | ova
supervisor_api | ok
version_api | ok
installed_addons | Samba share (12.6.1), Terminal & SSH (10.1.0), File editor (6.0.0), InfluxDB (5.0.2), Network UPS Tools (0.18.0), Get HACS (1.3.1), Matter Server (8.4.0), Mosquitto broker (7.0.1)
Dashboards
dashboards | 7
-- | --
resources | 7
views | 8
mode | storage
Network Configuration
adapters | lo (disabled), enp0s18 (enabled, default, auto), hassio (disabled), docker0 (disabled), veth9548f58 (disabled), veth681df95 (disabled), veth72c860f (disabled), veth42e2f73 (disabled), vethd111e49 (disabled), vethbebe947 (disabled), veth37566a3 (disabled), vethd77ea6b (disabled), veth5090ed1 (disabled), vethe9331db (disabled), vethe67184c (disabled), enp0s18.30 (disabled), enp0s18.40 (disabled)
-- | --
ipv4_addresses | lo (127.0.0.1/8), enp0s18 (192.168.3.139/24), hassio (172.30.32.1/23), docker0 (172.30.232.1/23), veth9548f58 (), veth681df95 (), veth72c860f (), veth42e2f73 (), vethd111e49 (), vethbebe947 (), veth37566a3 (), vethd77ea6b (), veth5090ed1 (), vethe9331db (), vethe67184c (), enp0s18.30 (), enp0s18.40 ()
ipv6_addresses | lo (::1/128), enp0s18 (fdb5:a65a:2e3b:28d3:f731:3bd6:3243:61b2/64, fe80::f83c:59ca:537c:7059/64), hassio (fe80::c024:67ff:fe48:dbd6/64), docker0 (fe80::84b8:e0ff:fe34:823/64), veth9548f58 (fe80::a098:b7ff:fe8c:d333/64), veth681df95 (fe80::e06e:eeff:fe19:317/64), veth72c860f (fe80::f0f9:faff:fe92:7030/64), veth42e2f73 (fe80::2450:38ff:fede:d9/64), vethd111e49 (fe80::4f4:5fff:fe6a:13af/64), vethbebe947 (fe80::848b:8eff:fe1c:ffd5/64), veth37566a3 (fe80::fc91:12ff:fe12:cade/64), vethd77ea6b (fe80::5c0e:a2ff:fed5:43ba/64), veth5090ed1 (fe80::749c:75ff:fe84:9a06/64), vethe9331db (fe80::208a:3dff:fedd:e635/64), vethe67184c (fe80::585b:86ff:fe95:d1a1/64), enp0s18.30 (fe80::1e7a:a84:1398:6353/64), enp0s18.40 (fe80::c64e:3aeb:a5da:281/64)
announce_addresses | 192.168.3.139, fdb5:a65a:2e3b:28d3:f731:3bd6:3243:61b2, fe80::f83c:59ca:537c:7059
Recorder
oldest_recorder_run | April 7, 2026 at 4:16 AM
-- | --
current_recorder_run | April 18, 2026 at 12:33 PM
estimated_db_size | 634.23 MiB
database_engine | sqlite
database_version | 3.49.2
### Supervisor diagnostics
[config_entry-hassio-76bb24bd37b50d14ed93037c4539f3b4.json](https://github.com/user-attachments/files/26860440/config_entry-hassio-76bb24bd37b50d14ed93037c4539f3b4.json)
### Additional information
_No response_
Contributor guide
Research direction
Start with supervisor/utils/dbus.py around sync_property_change and supervisor/host/network.py around check_connectivity(). Trace how DBusFatalError and DBusError are handled when the D-Bus socket is dead. Done means property-sync failures no longer become unhandled tasks and a D-Bus check failure remains unknown rather than falsely setting connectivity to false, while Supervisor updates can retry.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100