Recovery
What to do when you lose access to a vault.
TL;DR
Recovery is only possible if you set up a backup keyslot in advance. LUKSbox cannot recover a vault from the disk alone - that's the whole point of encryption.
If you set things up right, recovery is straightforward:
- Lost YubiKey, have a backup passphrase: unlock with the passphrase, enroll a new device, optionally revoke the lost slot.
- Forgot passphrase, have a working YubiKey: unlock with the device, enroll a new passphrase, revoke the old slot.
- Lost both: you cannot recover. There is no master backdoor.
Setting up for recoverability (do this BEFORE you need it)
For any vault you'd be sad to lose:
# 1. Create with FIDO2 + automatic backup passphrase
luksbox create my.lbx --kind fido2
# 2. Enroll a SECOND FIDO2 device (kept in a safe deposit box, etc.)
luksbox enroll my.lbx --fido2 --fido2-device /dev/hidraw4
# Optional 3: write the backup passphrase on paper, store separately
Now the vault has 3 keyslots. Loss of any 2 still leaves the third.
Lost device
# Unlock with backup passphrase (or backup device)
luksbox open my.lbx
# Enroll a replacement device
luksbox enroll my.lbx --fido2
# Find the lost device's slot index
luksbox info my.lbx
# Revoke the lost slot (won't actually erase what an attacker who has
# the device might have already extracted - see rotate-mvk below if
# you're worried about that)
luksbox revoke my.lbx --slot 0
# If you suspect the lost device was actually stolen + the attacker
# might have your backup passphrase too, rotate the MVK so any
# previously-extracted keys become useless:
luksbox rotate-mvk my.lbx
Forgotten passphrase
# Unlock with the FIDO2 device
luksbox open my.lbx --fido2
# Enroll a new passphrase
luksbox enroll my.lbx --passphrase
# Revoke the old passphrase slot
luksbox info my.lbx # find slot index
luksbox revoke my.lbx --slot <N>
Lost the .kyber seed file (hybrid-PQ vault)
The .kyber seed is required to derive the PQ shared secret. Without
it, the hybrid-PQ slot is dead - no recovery possible from the slot
alone.
If you have a non-hybrid keyslot in the same vault (passphrase or plain FIDO2), use that to unlock:
luksbox open my.lbx # use a non-hybrid slot
# Then enroll a new hybrid-PQ slot with a fresh seed
luksbox kyber-init /media/usb/new.kyber
luksbox enroll my.lbx --kind hybrid-pq --pq-hybrid /media/usb/new.kyber
If the hybrid-PQ slot was your only keyslot: vault is unrecoverable.
Corrupted header
If the inline header is damaged but you have a detached header backup:
luksbox open my.lbx --header /media/usb/my.hdr.backup
If you have an inline-mode vault and a previously-saved
header-backup, restore it directly:
luksbox header-restore my.lbx /media/usb/my.hdrbak
# (drop --no-verify only if the on-disk MVK is also unrecoverable)
Always-on advice: keep at least one header-backup (and a .hdr
copy if you use detached mode) on separate storage. Headers are
8 KiB - trivial to back up. See the
forensics page for the full damaged-header
walkthrough.
Corrupted chunk (one or more files refuse to read)
mount and ls work, but reading a specific file fails with
AEAD failure. The damage is local to that file's chunks.
# Locate the bad chunks (read-only)
luksbox check my.lbx
# Salvage what is still readable from the affected file
luksbox extract my.lbx /the/affected/file recovered.bin --tolerate-errors
The output file is the same byte length as the original, with 4 KiB zero ranges in place of each unrecoverable chunk. See the forensics page for the full chunk-corruption flow.
Vault refuses to open: tolerant recovery mode (v0.2.2+)
When Vfs::open fails with metadata blob deserialization failed
or per-inode AEAD errors on the chunk-list chain (the symptom of
the v0.2.1 durability bug
that v0.2.2 fixed), the vault carries inodes whose chunk pointers
no longer decrypt. Default open refuses the whole vault rather
than silently expose bytes-from-a-previous-flush as file
content. Recovery mode opt-in installs the broken inodes as
0-byte placeholders so you can mount read-only and copy out
every healthy file.
CLI / scripts
LUKSBOX_TOLERATE_BAD_CHUNK_LISTS=1 luksbox mount my.lbx /tmp/v
# Vault mounts read-only; broken files appear as 0-byte
# placeholders; healthy files read as normal.
cp -r /tmp/v ~/recovered/
luksbox umount /tmp/v
The LUKSBOX_DEBUG_OPEN=1 env var prints which parse step trips
during open (metadata head bytes, LBM magic match, postcard
error, per-inode v4_on_disk_to_in_memory result), useful for
narrowing down a damaged vault before trying tolerant mode.
Wizard (TUI)
When the wizard hits a MetadataDeserialize open failure, it
prompts "Try opening in recovery mode?" (default yes). On
confirm it re-authenticates with the tolerant flag set, then
prints the list of broken inode IDs / sizes / paths to stderr
before handing you the read-only mount.
GUI
The Open form has a "Recovery mode (read-only, skips broken files)" checkbox. Ticking it before unlock applies the toleration flag for that session. On a successful recovery-mode open with tolerated inodes, a modal lists every broken file's path + original size + AEAD-failure reason so you know what to re-source. Dismiss the modal to use the vault read-only; flush is refused while the recovery report is active.
What recovery mode guarantees
- The broken inodes are not persisted as 0-byte over the
original on-disk metadata. The new
Error::ReadOnlyMountrefuses every subsequent flush, so brute-force recovery against the originalchunks_externalpointers (via deep forensics, an older.meta-bak.tmp.*snapshot, etc.) remains possible later. - Healthy files decrypt and read normally. Only inodes whose chunk-list chain failed AEAD are placeholdered.
- Mount stays usable for
cp/ drag-and-drop into a fresh destination. Treat the mounted vault as a one-shot escape hatch: once you've copied out everything readable, unmount and start the broken-vault forensics workflow on the original.lbx.
Corrupted anchor
The .anchor sidecar is rollback-detection metadata, not unlock
material. If it's missing or corrupted:
luksbox open my.lbx --no-anchor # opens, prints rollback warning
luksbox anchor-rebuild my.lbx # rebuild from current vault state
Use --no-anchor only if you trust the vault hasn't been rolled
back (e.g. you control the storage).
Things LUKSbox cannot help with
- A vault file that's been overwritten with random data: encryption doesn't reconstruct lost ciphertext.
- A vault with all keyslots wiped: nothing to derive a key from.
- A passphrase you simply forgot, with no other keyslot: forever unrecoverable. Use a password manager OR write it on paper and store the paper securely. (Argon2id at 4 g/s would take 10^14 years to brute-force a 5-word EFF passphrase.)