home-assistant/core · error · AbortFlow
cannot_connect
cannot_connect
Error message
cannot_connect
What it means
AbortFlow with reason 'cannot_connect' raised in the Airzone local integration's config flow (discovered-connection step). After discovery finds the device, the flow calls airzone.get_version() to verify the local API is reachable; any AirzoneError or TimeoutError aborts setup with 'cannot_connect'. AbortFlow is not an error surfaced to the user as an exception — HA renders it as a discovery flow message keyed by the reason string.
Source
Thrown at homeassistant/components/airzone/config_flow.py:125
self._discovered_mac = discovery_info.macaddress
_LOGGER.debug(
"DHCP discovery detected Airzone WebServer: %s", self._discovered_mac
)
self._async_abort_entries_match({CONF_HOST: self._discovered_ip})
await self.async_set_unique_id(format_mac(self._discovered_mac))
self._abort_if_unique_id_configured()
options = ConnectionOptions(self._discovered_ip)
airzone = AirzoneLocalApi(
aiohttp_client.async_get_clientsession(self.hass), options
)
try:
await airzone.get_version()
except (AirzoneError, TimeoutError) as err:
raise AbortFlow("cannot_connect") from err
return await self.async_step_discovered_connection()
async def async_step_discovered_connection(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm discovery."""
assert self._discovered_ip is not None
assert self._discovered_mac is not None
errors = {}
base_schema = {vol.Required(CONF_PORT, default=DEFAULT_PORT): int}
if user_input is not None:
airzone = AirzoneLocalApi(
aiohttp_client.async_get_clientsession(self.hass),
ConnectionOptions(
self._discovered_ip,View on GitHub (pinned to 58a3fdb3ea)
Solutions
- Verify the Airzone WebServer is reachable from the HA host: curl http://<ip>:3000/api/v1/hvac (or the integration's documented endpoint).
- Confirm no duplicate config entry already uses that host (the flow aborts for duplicates just above this code, but leftover entries cause confusion).
- Check firewall/VLAN rules allowing HTTP from HA to the device, then retry discovery.
- If the IP is stale, reserve a static DHCP lease for the WebServer and rediscover.
Defensive patterns
Strategy: retry
Validate before calling
import asyncio, aiohttp
async def webserver_reachable(ip: str) -> bool:
try:
async with aiohttp.ClientSession() as s, asyncio.timeout(5):
async with s.get(f"http://{ip}:3000/api/v1/hvac") as r:
return r.status == 200
except (aiohttp.ClientError, TimeoutError):
return False Try / catch
from homeassistant.data_entry_flow import AbortFlow
try:
await hass.config_entries.flow.async_configure(flow_id, user_input)
except AbortFlow as err:
if err.reason == "cannot_connect":
# prompt user to check device/network and retry discovery
... Prevention
- Reserve a static DHCP lease for the Airzone WebServer.
- Ensure HA and the HVAC bridge are on the same VLAN/subnet before discovery.
- Verify the WebServer responds over HTTP before starting the flow.
When it happens
Trigger: Discovery finds an Airzone WebServer at _discovered_ip but the HTTP GET to its API (get_version) fails: wrong/unreachable IP, WebServer firmware blocking the API, port 3000 not reachable (though default is checked later), device rebooting, or the request exceeding the library timeout.
Common situations: mDNS discovery returning a stale IP after DHCP reassignment; VLAN/IGMP isolation between the HA host and the HVAC network; Airzone WebServer with old firmware that requires a different endpoint; device powered off mid-discovery.
Related errors
- {error}
- already_in_progress
- cannot_connect
- Credential is already linked to a user
- Unable find multi-factor auth module: {mfa_module_id}
AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14).
Data as JSON: /api/errors/f627e29ea9aa0615.
Report an issue: GitHub.