The Decision Tree: Which SSH Method Do You Actually Need?
Home Assistant OS (HAOS) is an immutable, appliance-like operating system. By design, it locks down the host root filesystem and disables standard SSH access to prevent users from accidentally breaking the Docker container architecture. When you search for how to SSH into Home Assistant Raspberry Pi, you will find three distinct methods. Picking the wrong one is the primary reason most users hit a wall.
| Method | Port | Access Level | When to Use (Decision Path) |
|---|---|---|---|
| Advanced SSH Add-on | 22 | Container (Home Assistant CLI) | Default Pick: You need to run ha CLI commands, check logs, or edit configuration.yaml. Use this for 95% of daily tasks. |
| OS-Level SSH (USB Key) | 22222 | Host Root (Read-Only mostly) | You need to modify host-level configs (e.g., cmdline.txt, Docker daemon, udev rules) that survive OS updates. |
| Serial UART Console | N/A (GPIO) | Host Root (Full TTY) | The network stack is bricked, the Pi is hanging on boot, or you need to debug kernel panics. |
Parts List and Hardware Pin Mapping (Serial Fallback)
If your network configuration is botched and you cannot reach Port 22 or 22222, the serial console is your lifeline. This requires physical access to the Raspberry Pi's GPIO header.
Required Hardware
- Compute Board: Raspberry Pi 4 Model B (4GB/8GB) or Raspberry Pi 5 (8GB) running HAOS.
- Serial Adapter: Adafruit TTL-232R-3V3 (or any 3.3V USB-to-TTL serial cable). Never use a 5V RS-232 adapter; it will fry the Pi's SoC.
- Jumper Wires: Female-to-female Dupont connectors.
GPIO Pin Mapping for UART Console
The Raspberry Pi exposes a primary UART on the GPIO header. You must connect the TX of your adapter to the RX of the Pi, and vice versa.
| Pi GPIO Pin | BCM Number | Function | Connect to Adapter Wire |
|---|---|---|---|
| Pin 6 | N/A | Ground (GND) | Black (GND) |
| Pin 8 | GPIO 14 | UART TXD | White (RXD) |
| Pin 10 | GPIO 15 | UART RXD | Yellow (TXD) |
Method 1: The Standard Add-on Route (Port 22)
This is the officially supported method for interacting with the Home Assistant CLI. It drops you into a container that has access to the /config directory and the ha command-line tool.
- Open your Home Assistant web UI and navigate to Settings → Add-ons → Add-on Store.
- Search for and install the Advanced SSH & Web Terminal add-on (community repository). Avoid the official 'Terminal & SSH' add-on, as it lacks advanced features and package management.
- Open the add-on configuration tab. Under Authorized Keys, paste your public SSH key (e.g.,
ssh-rsa AAAAB3... user@host). Alternatively, set a strong password, though key-based auth is highly recommended. - Toggle Show in sidebar and click Start.
- Connect from your terminal:
ssh -p 22 root@homeassistant.local(or use your Pi's static IP).
Method 2: OS-Level Access via Port 22222 (The USB Key Trick)
If you need to edit host-level files like /mnt/boot/config.txt (to enable specific hardware overlays) or inspect the underlying Docker engine, the Add-on won't work. HAOS includes a hidden developer SSH daemon on port 22222, but it only activates if it finds an authorized key on a USB drive during boot.
- On your main PC, generate an SSH key pair if you don't have one:
ssh-keygen -t ed25519 -C "haos-debug". - Format a small USB flash drive to FAT32.
- Create a file named exactly
authorized_keys(no.txtextension) in the root of the USB drive. - Paste your public key (
id_ed25519.pub) into this file and save it. - Plug the USB drive into the Raspberry Pi and reboot the host (Settings → System → Restart).
- During boot, HAOS udev rules detect the drive, import the key into the host's root
.sshdirectory, and start the Dropbear SSH daemon on port 22222. - Connect using:
ssh -p 22222 root@homeassistant.local.
Automating the Connection: Python Script with Error Handling
When building external monitoring dashboards or automated backup scripts, you need to query the HA CLI programmatically. The following Python script uses the paramiko library to establish a secure SSH connection, execute a command, and handle the specific failure modes common to Pi deployments.
Target Board Variant: Raspberry Pi 4 Model B / Raspberry Pi 5 running HAOS 11.x or later.
import paramiko
import socket
import sys
# Target configuration
HA_HOST = '192.168.1.50' # Use static IP, mDNS (.local) can be flaky in automated scripts
HA_PORT = 22 # Use 22 for Add-on, 22222 for Host OS
SSH_KEY_PATH = '/home/user/.ssh/id_ed25519'
def run_ha_command(command):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
print(f'Connecting to {HA_HOST}:{HA_PORT}...')
client.connect(
hostname=HA_HOST,
port=HA_PORT,
username='root',
key_filename=SSH_KEY_PATH,
timeout=10,
allow_agent=False,
look_for_keys=False
)
stdin, stdout, stderr = client.exec_command(command, timeout=15)
exit_status = stdout.channel.recv_exit_status()
output = stdout.read().decode('utf-8').strip()
errors = stderr.read().decode('utf-8').strip()
if exit_status == 0:
return output
else:
raise RuntimeError(f'Command failed with exit code {exit_status}: {errors}')
except paramiko.AuthenticationException:
print('ERROR: Authentication failed. Check if your public key is in the Add-on config or authorized_keys USB.')
sys.exit(1)
except socket.timeout:
print('ERROR: Connection timed out. The Pi may be hanging on boot or the network is down.')
sys.exit(2)
except socket.error as e:
print(f'ERROR: Network unreachable or port closed. OS Error: {e}')
sys.exit(3)
finally:
client.close()
if __name__ == '__main__':
# Fetch Home Assistant Core version via the ha CLI
result = run_ha_command('ha core info --raw-json')
print(f'HA Core Status: {result}')
Hardware Serial Fallback Code (PySerial)
If the network is entirely dead, you can automate the serial console using the GPIO UART pins mapped in the table above. This script targets the primary UART (/dev/ttyAMA0) which maps to GPIO 14 and 15.
import serial
import time
# GPIO 14 (TXD) and GPIO 15 (RXD) map to /dev/ttyAMA0 on Pi 4/5
SERIAL_PORT = '/dev/ttyAMA0'
BAUD_RATE = 115200
try:
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=2)
time.sleep(1) # Allow serial buffer to settle
# Send a newline to wake up the login prompt
ser.write(b'\n')
response = ser.read(ser.in_waiting or 1000).decode('utf-8', errors='ignore')
print(f'Serial Console Output:\n{response}')
except serial.SerialException as e:
print(f'Failed to open serial port {SERIAL_PORT}: {e}')
finally:
if 'ser' in locals() and ser.is_open:
ser.close()
Troubleshooting: Exact Error Strings and Ranked Causes
When your SSH connection fails, the terminal throws specific errors. Here is the diagnostic decision path for the three most common failures.
1. "ssh: connect to host 192.168.1.50 port 22: Connection refused"
What it means: The Pi is online and reachable at the IP level, but nothing is listening on the requested port.
- Cause A (Most Likely): You are trying to connect to Port 22 on the host OS. HAOS does not run an SSH daemon on port 22 at the host level. Fix: Use the Add-on, or switch to port 22222 with the USB key method.
- Cause B: The Advanced SSH Add-on is installed but stopped. Fix: Check the Add-on dashboard and verify the "Start on boot" toggle is active.
- Cause C: You are targeting port 22222, but the USB key import failed during boot. Fix: Ensure the USB drive is FAT32, the file is named exactly
authorized_keys, and check the HAOS supervisor logs for import errors.
2. "root@192.168.1.50: Permission denied (publickey)"
What it means: The SSH daemon is running, but it rejected your cryptographic identity.
- Cause A (Most Likely): You pasted your private key instead of your public key into the Add-on configuration. Fix: Ensure you are pasting the contents of
.pub(starts with ssh-rsa or ssh-ed25519), not the private key. - Cause B: File permissions on the host OS (Port 22222) are wrong. HAOS requires strict permissions. Fix: The USB import handles this automatically, but if you manually copied keys via a mounted filesystem, ensure
.sshis 700 andauthorized_keysis 600.
3. "ssh: Could not resolve hostname homeassistant.local: Name or service not known"
What it means: mDNS (Multicast DNS) is failing to resolve the .local address on your network.
- Cause A: Your PC lacks an mDNS resolver (common on older Windows machines without Bonjour). Fix: Use the Pi's static IP address instead of the hostname.
- Cause B: The Pi is on a different VLAN or subnet, and mDNS broadcasts are being blocked by your router. Fix: Assign a static IP via your router's DHCP reservation and connect via IP.
- Ping the Pi's IP address to verify Layer 3 network connectivity.
- Verify you are targeting the correct port (22 for Add-on, 22222 for Host).
- Confirm you are using the correct username (
rootis default for both Add-on and Host OS in HAOS).
Extending and Simplifying Your Build
Once you have stable SSH access, you can scale your automation or strip it back to basics depending on your needs.
How to Simplify
If you only need to occasionally check logs or restart a stubborn Zigbee2MQTT container, abandon the Python scripts and Port 22222 entirely. Rely solely on the Advanced SSH Add-on's built-in web terminal. It runs in your browser, requires no local SSH client configuration, and survives network topology changes because it routes through the Home Assistant ingress proxy.
How to Extend
For advanced users managing multiple Pi nodes or automated nightly backups:
- Ansible Integration: Use the Python script's logic to build an Ansible inventory. You can push
configuration.yamlupdates to the Pi via the Add-on's SSH port, using theha core restartcommand in your playbook's post-tasks. - Remote API Fallback: SSH is heavy for simple state checks. Extend your monitoring by pairing the SSH script with the Home Assistant REST API. Use the API for sensor data polling, and reserve SSH strictly for filesystem modifications and container restarts.
- Watchdog Timers: If you are running custom hardware overlays via Port 22222 host access, enable the Raspberry Pi's hardware watchdog (
dtparam=watchdog=oninconfig.txt) to automatically reboot the SoC if your custom host-level daemon hangs the kernel.
For further reading on HAOS architecture, refer to the official Home Assistant OS documentation. For deep-dives into the Raspberry Pi UART hardware configuration, consult the Raspberry Pi hardware configuration guides.






