# How Recovery Mode and Debug Mode Affect Home Assistant Startup

> Understand how Recovery Mode and Debug Mode impact Home Assistant startup. Learn about core HTTP services, custom component skipping, verbose logging, and runtime validation.

- Repository: [Home Assistant/core](https://github.com/home-assistant/core)
- Tags: internals
- Published: 2026-02-28

---

**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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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:

```python
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:

```python
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`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py), lines 289‑291), the logging level is determined by:

```python
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`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py), line 284):

```python
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`](https://github.com/home-assistant/core/blob/main/homeassistant/helpers/template/__init__.py), line 556):

```python
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`](https://github.com/home-assistant/core/blob/main/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:

```bash
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:

```python
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`](https://github.com/home-assistant/core/blob/main/configuration.yaml):

```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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/loader.py) lines 300‑302) and the bootstrap loads only the `recovery_mode` integration plus HTTP settings ([`bootstrap.py`](https://github.com/home-assistant/core/blob/main/bootstrap.py) lines 882‑891).
- **Debug mode** is enabled via the `--debug` CLI flag, setting `hass.config.debug = True` ([`bootstrap.py`](https://github.com/home-assistant/core/blob/main/bootstrap.py) lines 296‑298).
- Debug mode lowers the logging threshold to `INFO` ([`bootstrap.py`](https://github.com/home-assistant/core/blob/main/bootstrap.py) lines 289‑291), enables asyncio loop debugging ([`runner.py`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/homeassistant/helpers/template/__init__.py) line 556) and the dispatcher enables expensive thread-verification logic ([`homeassistant/helpers/dispatcher.py`](https://github.com/home-assistant/core/blob/main/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`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py).