Home Assistant Backup & SSD Migration Gone Wrong
The Complete CLI Restore Guide
What This Post Is About
The plan: Migrate Home Assistant from a dying SD card to an SSD on a Raspberry Pi 5. Flash, restore backup, done in 30 minutes.
What actually happened: The onboarding "Restore from backup" screen is broken — 500 Internal Server Error in Chrome, infinite spinner in Safari. This is a known bug that's been open for months. On top of that, USB boot failed, two drives caused a health error, and the SD card had no space for add-ons.
The solution: A full CLI-based restore via SSH and SCP that bypasses the broken web UI entirely.
If you're stuck with a broken HA restore — whether from an SD card failure, SSD migration, or just a fresh install that won't accept your backup — this guide covers every failure mode I hit and how to get past them. Hopefully it saves you the afternoon I lost.
And before someone says "you should have read the documentation" — yes, I did. Flashing HAOS, restoring a backup, migrating to an SSD — none of this should be hard. It's a standard workflow that thousands of people go through. The fact that it requires a multi-step CLI workaround because the web UI has been broken for months is not a documentation problem, it's a product problem. This process should just work.
I also want to give a shoutout to Claude — having an AI assistant that could SSH into the Pi, debug errors in real-time, and iterate on CLI commands with me made this entire process manageable. Without it, I'd probably still be staring at that 500 error.
Tip: Dealing with this right now? Copy the URL (↗ button top right) and feed this page to your AI assistant as context — it'll help you adapt the steps to your specific setup.
What Failed (And Why)
1. USB Boot from SSD
SanDisk SSD Plus 250GB via a USB 3.0 SATA adapter. Flashed HAOS, plugged it in, and... nothing. Tried USB 3.0, USB 2.0, updated the EEPROM boot order to USB-first. No boot.
The frustrating part: I couldn't even check the adapter's chipset at this point — lsusb only works once the system is running, and the system wouldn't boot from the SSD. I only found out later (after the full restore was complete) that the adapter has an ASMedia ASM1153 chipset (174c:1153), which is supposedly boot-compatible. Still investigating why it refused. Check the Hardware Notes section below for known compatible chipsets.
2. Onboarding "Restore from Backup" — 500 Error
Flashed HAOS onto a new SD card, booted, clicked "Restore from backup":
500 Internal Server Error — Server got itself in trouble
Safari just hung with an infinite spinner. Both browsers, both old and new SD cards. It's a known bug in the onboarding upload endpoint. Don't rely on the web restore — have a CLI plan.
3. Two HAOS Drives — duplicate_os_installation
Both SD card and SSD had HAOS partitions. The Supervisor threw:
system is not healthy - duplicate_os_installation
All restore operations blocked. Even the UI repair dialog returned 401: Unauthorized.
Fix: Erase the SSD completely on your Mac first — Disk Utility → FAT32 → GUID Partition Map. Never have two drives with HAOS partitions connected simultaneously.
4. 8GB SD Card — No Space for Add-ons
After onboarding, tried to install SSH:
not enough free space (0.0GB) left on the device
Fix: Plug in the erased SSD first → Settings → System → Storage → Move datadisk. Hot-plug is fine. After reboot you have the full SSD capacity.
The Working Solution: CLI Restore
Here's the step-by-step procedure that actually worked — from a completely fresh HAOS to a fully restored system.
Step 1: Flash and Onboard
Use Raspberry Pi Imager:
- Device: Raspberry Pi 5 (or your model)
- OS: Other specific-purpose OS → Home assistants → Home Assistant OS
- Storage: Your SD card
Boot, wait 5-10 minutes, open http://<IP>:8123.
Do NOT click "Restore from backup." It's broken.
Click "Create my smart home" instead. Create a throwaway account — it gets overwritten during restore. Click through the wizard.
Step 2: Set Up Data Disk (If SD Is Small)
If your SD card is 8GB or less:
- Plug in the erased SSD via USB (hot-plug while running is fine)
- Settings → System → Storage → Move datadisk
- Wait for reboot (~2-3 minutes)
- Now you have full SSD capacity for add-ons and backups
Step 3: Install SSH
- Settings → Add-ons → Add-on Store → "Terminal & SSH" (
core_ssh) - Install → Configuration: set a password, set port 22 under Network
- Save → Start
On your Mac, clear the old host key (new HAOS = new key):
ssh-keygen -R <IP>Step 4: Upload Your Backup
scp "/path/to/backup.tar" root@<IP>:/backup/Accept the host key prompt, enter the password from Step 3. A ~190MB backup takes about 1 minute over LAN.
Step 5: Register and Restore
This is the step most guides miss — backups copied via SCP are invisible to the Supervisor:
ha backups reload
ha backups listThe slug will be different from the original. Use the new one.
Now the restore. The CLI syntax is confusing — here's what does NOT work:
ha backups restore <slug> --everything # flag doesn't exist
ha backups restore <slug> --app app1 app2 # "accepts 1 arg(s), received 3"
ha backups restore <slug> --addons # deprecatedCorrect syntax — each app and folder needs its own flag:
ha backups restore abc12345 \
--app a0d7b954_tailscale \
--app core_mosquitto \
--app 45df7312_zigbee2mqtt \
--app a0d7b954_ssh \
--app cebe7a76_hassio_google_drive_backup \
--app 5c53de3b_esphome \
--app a0d7b954_nut \
--folders ssl \
--folders media \
--folders shareFind your app slugs with ha backups list. The restore takes 10-30 minutes. SSH will drop — that's normal, HA is restarting.
Step 6: Log In
Navigate to http://<IP>:8123 and log in with your original credentials. The throwaway account is gone.
After the Restore
Fix the SSH Port Conflict
If your backup had the Advanced SSH add-on, it'll fight with the temporary core_ssh over port 22. Uninstall the temporary one — just stopping it isn't enough, it auto-starts on reboot:
ha apps uninstall core_sshRe-add Your SSH Key
The restored Advanced SSH add-on may not have your key. Either add it via the HA Web Terminal:
mkdir -p ~/.ssh
echo "ssh-ed25519 AAAA...your_key..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysOr paste it in Settings → Add-ons → Advanced SSH → Configuration → Save → Restart.
Reconnect Zigbee Devices
After a long coordinator outage, devices won't reconnect on their own.
- Mains-powered devices (plugs, repeaters): power-cycle them. Start with routers — they're the mesh backbone.
- Battery devices (sensors, buttons): trigger them physically. Can take minutes to hours.
Re-add Network Storage
Settings → System → Storage → Add Network Storage. One gotcha: mount names can't contain hyphens, only underscores. STATUS_LOGON_FAILURE usually means wrong credentials or SMB not enabled for that user on the NAS.
Restore Missing Apps from an Older Backup
If your initial restore missed some apps, you can grab them from another backup without overwriting HA Core:
ha backups restore <slug> --homeassistant=false --app <app> --folders media --password='<pw>' --location=<MountName>Key details:
--homeassistant=falseprevents a core downgrade from an older backup--password='...'— single quotes for special characters--location=MountName— when restoring from network storage- The HA terminal doesn't support
\line breaks — write it all on one line
Verify Everything
ha apps list # All apps running?
ha core check # Config valid?
ha mounts info # Network storage connected?Check automations for duplicate IDs (a common post-restore issue):
python3 -c "
import yaml
with open('/config/automations.yaml') as f:
a = yaml.safe_load(f)
print(f'Total: {len(a)}')
ids = [x.get('id','') for x in a]
dupes = [i for i in set(ids) if ids.count(i) > 1 and i]
if dupes: print(f'DUPLICATE IDs: {dupes}')
else: print('No duplicate IDs')
"Watch out for missing - id: fields — the YAML parser silently merges those automations into the previous one, creating phantom duplicates.
Things that may need re-authentication after restore:
- Alexa / Amazon integrations
- Google Drive Backup add-on
- Fritz!Box integration
- Any OAuth-based integration
CLI Quick Reference
ha backups list # List all backups
ha backups reload # Required after manual file copy
ha backups restore <slug> # Full restore
ha backups restore <slug> \
--app <slug> --folders <name> # Partial (repeat each flag)
ha apps list # List apps (formerly "addons")
ha apps uninstall <slug> # Remove an app
ha core info # System status
ha host reboot # When all else failsNote: --addons still works but is deprecated. Use --app.
Hardware Notes
For USB boot on a Raspberry Pi 5:
| Adapter | Boot? |
|---|---|
| ASMedia ASM1153E | Yes |
| JMicron (various) | Problematic |
| Official RPi NVMe M.2 HAT+ | Yes |
Check with lsusb (only possible once the system is fully running) — 174c:1153 = ASMedia, 152d:xxxx = JMicron.
If your adapter won't boot, the SD boot + SSD data disk approach works well. The SD only handles the bootloader (minimal writes), while the SSD takes the database writes that kill SD cards.
Lessons Learned
- The Home Assistant backup restore process is broken.
SCP + ha backups restoreis the reliable path. - Check USB-SATA adapter chipsets with
lsusb— but you can only do that after the system is fully restored, not before boot. - Erase any drive that previously had HAOS before using it as a data disk. Set up your data disk before installing anything on a small SD card.
ha backups reloadis required after copying files manually. Slugs change after upload.- Each
--appand--foldersneeds its own flag.--everythingdoesn't exist.--addonsis deprecated. - Uninstall
core_ssh, don't just stop it — it auto-starts on reboot and blocks port 22. - Power-cycle Zigbee routers first after a long outage. Battery devices follow.
- Use
--homeassistant=falsewhen restoring from an older backup. Encrypted backups need single-quoted passwords. - The HA terminal doesn't support
\line breaks — one line or nothing. - Check for missing automation IDs after restore — they cause phantom duplicates.
Written after spending an entire afternoon fighting Home Assistant on a Raspberry Pi 5. Hopefully it saves you the same pain.
This post was written with the help of Claude Code — the same AI that helped me debug the actual restore process. All facts, failures, and frustrations are my own.