Main

How to Reconstruct a Forgotten Z-Wave Network Key from Backup Files You Didn’t Know Existed

Every Z-Wave network that uses security runs on one or more network keys. They are 16-byte values, written as 32 hexadecimal characters, and they encrypt the commands between your controller and any device you included with S0 or S2 security. Up to four can be in play: one S0 legacy key and three S2 keys (Unauthenticated, Authenticated, Access Control). The Access Control key is the one your smart lock or garage controller was paired with. Lose them — dead SD card, wiped Docker volume, a controller swap gone sideways — and every secured device stops trusting the rebuilt system. The official answer is to exclude and re-include each device by hand. The unofficial answer is better: those keys were written to disk in at least two places, and every Home Assistant backup you own captured them. So this is a recovery job, not a rebuild. Here is where the files live and how to read them.

Two engineers reviewing configuration files on a computer monitor

What You Are Actually Looking For

A Z-Wave network key is 16 bytes — 128 bits — and every tool in the stack writes it as 32 hexadecimal characters, sometimes with 0x prefixes and commas in older formats. Four keys can be in play on a current Z-Wave JS setup:

  • S0 legacy key — the original single network key. Pre-2016 devices used it, and so did plenty of locks included before S2 shipped.
  • S2 Unauthenticated — encrypted traffic, but nothing verifies the device identity at inclusion.
  • S2 Authenticated — encrypted, and the device DSK (that QR code on the box) was checked at inclusion.
  • S2 Access Control — the highest class, required for locks and garage controllers.

Z-Wave JS UI groups these in a securityKeys object under the names S0_Legacy, S2_Unauthenticated, S2_Authenticated, and S2_AccessControl. The Home Assistant integration uses lowercase field names like s2_access_control and network_key. Different labels, same 32 characters. If you want the primary source on naming and format, the Z-Wave JS UI security keys documentation has it.

One thing worth checking before you start digging: devices included without security — most mains-powered switches and sensors — never touch these keys at all. If you never included anything securely, you do not have a recovery problem. Generate fresh keys and your unsecured nodes keep working like nothing happened. The key only matters for devices included with S0 or S2, and in practice that means locks, garage doors, and the occasional thermostat.

Why You Cannot Pull the Key Off the Devices

S2 inclusion runs an ephemeral ECDH key exchange, and the resulting key ends up inside the device with no over-the-air read command to pull it back out. No vendor tool exports it from a lock. The controller stick holds the keys in its non-volatile memory (NVM), and NVM backup tools exist — but restores are only supported between identical stick models and matching firmware families in most cases. I have watched a 700-series NVM restore land on the same model. I have not seen a supported path from a 700-series stick to an 800-series one, and I would not trust an unsupported path with the only copy of anything. Treat NVM backup as hardware-replacement insurance. It is not a key-recovery method.

That leaves files. Files you almost certainly have, because Home Assistant’s backup system copies the entire configuration directory — the hidden .storage folder included — plus the add-on data directories where Z-Wave JS UI keeps its store. If you turned on scheduled backups under Settings → System → Backups in a recent version, you have months of candidates sitting on whatever storage you pointed them at.

The Four Places the Key Gets Written

1. Home Assistant’s .storage/core.config_entries

Every integration configured through the UI stores its data in this JSON file inside the config directory. The Z-Wave JS entry can contain network_key, s2_unauthenticated, s2_authenticated, and s2_access_control, depending on how the setup was done. If your backups reach back far enough, you may also find an old OpenZWave entry carrying an S0 key directly — pre-2021 installs did exactly that. The integration documentation describes the setup modes if you need to confirm which one you used.

2. Z-Wave JS UI’s settings.json

If you run Z-Wave JS UI — as an add-on, a Docker container, or a bare process — its store directory contains settings.json with the securityKeys object. In a full Home Assistant backup, add-on data lands under addons/data/ with the add-on slug as the folder name: something like a0d7b954_zwavejs2mqtt for the community add-on or core_zwave_js for the official one, depending on what you ran and when. The file sits at the root of the data directory or inside a store folder, depending on how the process was launched. I do not memorize this layout. I do not have to — the field names are distinctive enough to search for.

3. Add-on options and configuration.yaml

Older setups passed keys as add-on options, which the supervisor stores in its own data. Older still — the OpenZWave era — the S0 key sat directly in configuration.yaml as a network_key: line with comma-separated 0x values. Any snapshot from that period carries it in plain text.

4. Z-Wave JS UI’s own snapshot files

The UI’s backup feature writes JSON snapshots of the network into its store directory. I will not claim these always contain key material — versions have differed, and I have not verified every release — but they live in the same directory tree as settings.json, so a recursive search hits them for free.

The Recovery Procedure, Step by Step

I have done this twice. Once for my own garage controller after a stick swap, once for a neighbor’s front-door lock. Both recoveries took under 20 minutes once the backup was located, and both times, finding the backup file took longer than reading it.

Step 1: Work on a copy, never the live system

Do not restore an old backup over your running Home Assistant to get the keys. A restore overwrites the database, the Zigbee config, everything — it rolls you back months for the sake of 128 bytes. Copy the backup file to a scratch folder and extract the copy. Home Assistant documents what a full backup includes in its backup guide; worth a read before you assume a partial backup has what you need.

Step 2: Extract and search

A Home Assistant backup is a tar archive containing, among other things, homeassistant.tar.gz — the configuration directory — plus the add-on data. On Linux or macOS:

mkdir -p /tmp/zkey && cd /tmp/zkey
tar -xf ha_backup_2024-03-01.tar
tar -xzf homeassistant.tar.gz -C config
grep -riE 'securityKeys|s2_access_control|network_key' .

On Windows, 7-Zip opens both layers without touching the command line. The field-name search is the high-signal move here. Searching for any 32-character hex string (grep -rE '[0-9a-fA-F]{32}') also works, but backups are full of checksums and tokens, and you will spend ten minutes squinting at false positives. Names first, hex second. One wrinkle: depending on the Home Assistant version, add-on data may appear as plain folders or as per-add-on archives. Open them all and run the search again.

Developer working through terminal commands on a laptop

Step 3: Normalize the format

If the hit is from the OpenZWave era, it looks like 0x01, 0x02, 0x03, ... Strip the 0x prefixes, the commas, and the spaces, and you are left with your 32 hex characters. Case does not matter. Z-Wave JS UI and the Home Assistant integration both want the plain 32-character form, no 0x.

Step 4: Verify before you trust it

Load the recovered keys into the running system — stop the add-on or container first, edit the settings or reconfigure the integration, then start it — and check a node you know was included securely. In Z-Wave JS UI, a lock’s node detail shows its security class; it should read S2 Access Control, or S0 for an older lock. Send one command. If the lock actuates, the key is right and you are done. If the driver log fills with decryption failures and secure commands go unanswered, you found a key from before a deliberate regeneration — keep searching earlier or later backups.

One subtlety worth knowing: keys do not change when you add devices. They only change if you regenerate them on purpose. So a backup taken any time between original key generation and today holds the same values that paired your lock. The newest backup is not special. Half-forgotten .tar files on a NAS or an old USB stick from migration day are all candidates.

When No Backup Has the Key

If the search comes up empty — no Home Assistant backups, no Docker volume copies, no old SD card in a drawer — the keys are gone. Three honest options:

  • Re-include the secured devices with fresh keys. Exclude each device, include it again with S2, verify the DSK for anything on an exterior door. Per device that is 5 to 15 minutes if it is physically reachable. One lock and a garage controller is an evening. Fifteen secured devices is a weekend, plus rework of scenes and entity IDs, since node IDs change.
  • NVM restore to an identical stick. Possible if your dead controller and its replacement are the same model. Verify the vendor’s support statement for your exact model and firmware before depending on it; I cannot verify every vendor tool’s behavior, and this is a bad place for assumptions.
  • Decide you did not need it. If the only secured device is a lock with a physical cylinder, and everything else is unsecured switches and sensors, fresh keys plus one re-included lock may be the entire cost of the incident.

A concession, since nobody ever asks for one: if this recovery work protects a single garage door you can already open with a physical button, the engineering answer may be a plain switch and a keyed deadbolt. Security keys earn their maintenance cost on exterior-entry devices. On interior lighting, they buy you almost nothing.

Documenting the Key So This Does Not Happen Twice

Once recovered, the key needs a home with better durability than a config directory on a machine you might reformat. Two homes, actually:

  • A password manager entry with all four keys labeled by class (S0, S2 Unauthenticated, S2 Authenticated, S2 Access Control), the date each was generated, and the controller model and serial they belong to. Digital survives house moves and dead drives; it fails when the account is lost or you cannot get in during a crisis of your own making.
  • A printed card in the drawer with the router passwords and insurance papers. Paper survives dead batteries and forgotten master passwords; it does not survive a fire or a burglary. Neither storage covers all the failure modes alone. Together they cover most of them.

Person writing notes at a desk next to a laptop

Treat the file like a house key, because functionally it is one: anyone holding the S2 Access Control key and RF range of your network can command secured devices. Never paste keys into a forum post or a GitHub issue when asking for help. Redact to the first four characters if you need to show format.

Do not plan on rotation as a control, either. Z-Wave has no network-wide key rotation; changing a key means re-including every device that uses it. These are long-lived credentials, so the effort belongs in storage security and access control on the copies, not in periodic changes.

This key inventory is one row of a bigger table — credentials, keys, and recovery paths for every controller in the house. I keep that list as part of the process described in How to Audit the Small Systems That Quietly Run Your Week, and a twice-a-year pass takes about 20 minutes. If you have just recovered your keys, do the audit while the file locations are fresh in your head. You will never have better recall of where things live than right after a scare.

FAQ

Can I recover the network key from the controller stick itself?

Not portably. The stick’s NVM contains the keys, and NVM backup tools exist, but restores are generally only supported to the same model and firmware family, and some vendor tools encrypt or restrict the export. For key recovery, files are the reliable path. NVM backup is for replacing a dead stick with an identical one.

Do I need all four keys, or just the S2 Access Control key?

You need whichever keys your secured devices were actually included with. Locks and garage controllers typically use S2 Access Control; older locks use S0. Unsecured devices ignore all four. If you are rebuilding, record all of them anyway — future inclusions will ask for them, and guessing later is how this article happens again.

Is it safe to post my recovered key when asking for help online?

No. Redact it. With the S2 Access Control key and physical proximity, an attacker can send commands to your secured devices. Support volunteers need the format, the field names, and at most the first few characters to help you.

The only backup I can find predates my lock. Will its keys still work?

Almost certainly, yes. Keys persist across device inclusion; they only change if you deliberately regenerate them. Any backup taken after the keys were first generated holds the same values that paired your lock. One exception: if you regenerated keys at some point, match the backup date to the period when the lock was included.

If you take one procedure away from this: search before you rebuild. The rebuild path costs an evening per handful of secured devices and rewrites node IDs. The search path costs about 20 minutes and a tar command. On the day a controller dies, the difference is whether the garage lock works before dinner. And if the search turns up nothing, you have still learned exactly what your next backup needs to contain — which is a better ending than most dead-controller stories get.