How Recovery Mode and Debug Mode Affect Home Assistant Startup

Recovery mode skips custom components and loads only core HTTP services when configuration parsing fails, while debug mode enables verbose logging, async loop debugging, and extra runtime validation checks throughout the startup sequence.

Home Assistant's startup behavior is governed by the bootstrap routine in homeassistant/bootstrap.py within the home-assistant/core repository. Two critical flags—recovery mode and debug mode—are evaluated early in async_setup_hass and fundamentally alter how the application initializes, loads integrations, and validates runtime behavior.

What Is Recovery Mode in Home Assistant?

Recovery mode is a failsafe startup state that activates when Home Assistant cannot parse configuration.yaml or fails to initialize a core integration. When triggered, the system recreates the HomeAssistant object with recovery_mode=True and loads a minimal configuration.

According to the source code in homeassistant/bootstrap.py (lines 260‑300), the flag is set via RuntimeConfig.recovery_mode and stored in hass.config.recovery_mode. If the YAML parser returns None or basic_setup_success is False, the bootstrap routine enters recovery mode and reloads only the recovery_mode integration and existing HTTP settings (lines 882‑891).

What Is Debug Mode in Home Assistant?

Debug mode is a diagnostic flag enabled via the --debug CLI argument. It activates comprehensive logging and runtime validation without altering the integration loading sequence.

When --debug is passed, runtime_config.debug is set to True and propagated to hass.config.debug in async_setup_hass (homeassistant/bootstrap.py, lines 296‑298). This triggers three primary effects: the core logger level drops to INFO (lines 289‑291), the asyncio event loop policy switches to a debug-friendly implementation (homeassistant/runner.py, line 284), and several subsystems enable expensive thread-safety checks that are normally skipped in production.

How Recovery Mode Alters the Startup Sequence

Recovery mode fundamentally changes what code executes during bootstrap by filtering component loading and configuration parsing.

Skipping Custom Components

When hass.config.recovery_mode is True, the loader explicitly skips discovery of custom components. In homeassistant/loader.py (lines 300‑302), the function _get_custom_components checks the flag and returns an empty dictionary, preventing any user-defined integrations from loading.

Minimal Configuration Loading

If the initial configuration parse fails, the bootstrap routine catches the HomeAssistantError and recreates the core object:

except HomeAssistantError as err:
    _LOGGER.error(
        "Failed to parse configuration.yaml: %s. Activating recovery mode",
        err,
    )
    recovery_mode = True

After the final recreation, the system loads only:

await async_from_config_dict(
    {"recovery_mode": {}, "http": ...},  # Minimal config

    hass
)

This leaves the UI and most integrations unavailable, logging "Starting in recovery mode" while preserving HTTP access for administrative repair.

How Debug Mode Changes Runtime Behavior

Debug mode does not skip integrations but instead injects validation and verbosity into existing subsystems.

Verbose Logging Configuration

In async_enable_logging (homeassistant/bootstrap.py, lines 289‑291), the logging level is determined by:

logger.setLevel(logging.INFO if runtime_config.debug else logging.WARNING)

This ensures that DEBUG and INFO level messages from core components appear in the logs.

Asyncio Event Loop Debugging

The runner configures the event loop policy based on the debug flag (homeassistant/runner.py, line 284):

loop = asyncio.new_event_loop()
if runtime_config.debug:
    loop.set_debug(True)

This enables asyncio's built-in debug mode, which logs slow callbacks and unawaited coroutines.

Template and Dispatcher Safety Checks

When hass.config.debug is True, the template engine verifies that rendering occurs only within the event loop thread (homeassistant/helpers/template/__init__.py, line 556):

if self.hass and self.hass.config.debug:
    # Verify we are running in the event loop

    ...

Similarly, the dispatcher enables expensive thread-verification logic that is normally bypassed in production to save CPU cycles (homeassistant/helpers/dispatcher.py, lines 10‑13).

Practical Code Examples

Starting Home Assistant in Debug Mode

Launch the core application with verbose logging and async debugging enabled:

hass --debug

This sets runtime_config.debug = True, which propagates through the bootstrap and runner systems.

Checking Runtime Flags

Within a custom component or script, verify the current operating mode:

if hass.config.debug:
    _LOGGER.info("Debug mode is active – extra checks are enabled")

if hass.config.recovery_mode:
    _LOGGER.warning("Running in recovery mode – many integrations are disabled")

Simulating Recovery Mode

To force recovery mode for testing, introduce a deliberate syntax error in configuration.yaml:

homeassistant:
  name: My Home
  # Intentional syntax error: missing colon

  latitude 52.0

When the bootstrap routine catches the HomeAssistantError, it automatically recreates the HomeAssistant instance with recovery_mode=True, loading only the minimal configuration required for HTTP access and repair.

Summary

  • Recovery mode activates when configuration.yaml parsing fails or core integrations fail to start, triggering a recreation of the HomeAssistant object with hass.config.recovery_mode = True.
  • In recovery mode, the loader skips custom components (loader.py lines 300‑302) and the bootstrap loads only the recovery_mode integration plus HTTP settings (bootstrap.py lines 882‑891).
  • Debug mode is enabled via the --debug CLI flag, setting hass.config.debug = True (bootstrap.py lines 296‑298).
  • Debug mode lowers the logging threshold to INFO (bootstrap.py lines 289‑291), enables asyncio loop debugging (runner.py line 284), and activates expensive thread-safety checks in the template engine and dispatcher.

Frequently Asked Questions

How do I start Home Assistant in recovery mode manually?

You cannot directly pass a "recovery mode" CLI flag. Instead, recovery mode triggers automatically when the bootstrap routine fails to parse configuration.yaml or cannot initialize a core integration. To force it for testing, introduce a deliberate syntax error in your configuration file, such as a missing colon after a key. The system will catch the HomeAssistantError, log the failure, and restart in recovery mode with only the HTTP interface and recovery tools available.

What is the difference between safe mode and recovery mode in Home Assistant?

Safe mode (legacy terminology) and recovery mode refer to the same failsafe startup state. In the current home-assistant/core codebase, the feature is implemented as recovery mode via the recovery_mode configuration flag. When active, it prevents loading of custom components and restricts the system to a minimal set of core integrations, specifically the recovery_mode integration and your existing HTTP configuration, allowing you to repair a broken configuration.yaml via the web interface.

Does debug mode slow down Home Assistant startup?

Debug mode adds negligible overhead to the startup sequence itself, but it enables runtime checks that consume CPU cycles during normal operation. Specifically, the template engine performs thread-safety verification (homeassistant/helpers/template/__init__.py line 556) and the dispatcher enables expensive thread-verification logic (homeassistant/helpers/dispatcher.py lines 10‑13) only when hass.config.debug is True. Additionally, verbose logging generates significantly more I/O. For production environments, you should omit the --debug flag to avoid these performance penalties.

Which CLI flags control startup behavior in Home Assistant?

The primary CLI flag affecting startup diagnostics is --debug, which sets runtime_config.debug and propagates through to hass.config.debug. This flag enables verbose logging, asyncio loop debugging, and extra validation checks. There is no direct --recovery-mode CLI flag; instead, recovery mode is an automatic failsafe triggered by configuration parsing errors or core integration failures. Other relevant startup flags include --config to specify the configuration directory and --skip-pip to bypass package installation, both of which interact with the bootstrap routine defined in homeassistant/bootstrap.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →