Safety, recovery, and honest limitations
Beta (v0.9.2 ). DedupCommando deletes and relinks real files, so it is built around layered safeguards. This page is a summary: the authoritative reference is Safety, recovery and limitations, and chapter 3 of the manual walks through every command. Read one of them before your first apply, and keep backups.
Is it safe to delete duplicate files?
Only if a mistake can be undone, and DedupCommando is designed around that. A scan never modifies your files: the walk, hash and group phases change nothing on the filesystem. Nothing is deleted or relinked until you review the plan and confirm it with Y, and even then a "delete" is a move into a quarantine, made under a fresh ZFS snapshot.
Layers of protection
Every destructive batch (delete, hardlink or reflink) runs behind these guardrails:
- A ZFS snapshot of every dataset in the batch, taken before the first action and named like
tank@dedcom-20260527-143215-512874000-4821-0. If any snapshot fails, the whole batch is aborted and no action runs; ifzfscannot be found, dedcom cancels the action rather than skip the snapshot. Snapshots are never removed automatically (details). - Quarantine instead of unlink. "Delete" moves the file to
<mountpoint>/.dedcom-quarantine/<timestamp>/<path-relative-to-dataset>at the root of its dataset, keeping permissions, owner and extended attributes. Scans skip that directory, and its space comes back only when you purge it (details). - Revalidation right before each action. A symlink-swap check and a size check always run, then a content check: in the default Hybrid mode each distinct file is hashed once per batch and re-checked with
statbetween actions, while--strict-verifyre-hashes target and keeper every time. A mismatch cancels only that action; the rest of the batch continues (details). - Atomic publish. Moves use
renameat2(RENAME_NOREPLACE), so there is no check-then-rename window on the destination. A hardlink or reflink takes the target's place only after the original is evacuated to quarantine, and if publishing fails, the original is restored automatically (details). - Single-instance lock. One writer holds
~/.local/state/dedcom/dedcom.lock; a second instance can open read-only, and headless modes exit with an error instead of prompting.--forceseizes the lock while the old process keeps running, so use it only when you are certain that process is dead (details). - Cross-dataset moves are refused, with a ready-to-run
rsynchint, because a silent copy-and-delete would lose owner, permissions, ACLs and xattrs, inflate sparse images and break hardlinks (details). - Consent and a resource governor. A one-time notice must be accepted before first use. The Idle scan profile (one thread,
nice 19andionice idle) keeps a scan from starving running VMs or backups (details).
Recovering deleted duplicates: one file or a whole batch
The Summary screen at the end of an apply lists the snapshots it created and the quarantine directory it used. Note both.
Restore a single file without a rollback
You do not need a rollback to bring back one file. Find it in the quarantine and move it to its original path:
find /tank/.dedcom-quarantine -type f -name 'photo.jpg'
mv /tank/.dedcom-quarantine/20260527-143215-512874000-4821-0/media/photo.jpg /tank/media/photo.jpg
If a hardlink now occupies that path, remove it first with rm /tank/media/photo.jpg (this removes only the link, not the original in the group), then run the mv. See bringing back one file.
Roll back a whole batch
If the whole batch was wrong, roll back each affected dataset to its snapshot:
zfs rollback tank@dedcom-<ts>
zfs rollback tank/media@dedcom-<ts>
Warning: a rollback returns the entire dataset to the moment of the snapshot, so everything written to it since, by any program, is lost too. If anything else wrote to the dataset after the batch, restore the files you need from the quarantine instead; ls /tank/.dedcom-quarantine/<ts>/ shows what was evacuated (details).
If an apply stopped early
Esc stops an apply only after the current action finishes; the process can also be cut off between actions. Either way the snapshots already exist, the originals of finished actions are in quarantine, and the actions not yet reached keep their marks. Press F11 again to finish, or roll back as shown above (details).
Purging the quarantine safely
Quarantined files and dedcom snapshots keep using pool space until you remove them, and removing them cannot be undone.
- Wait. The manual recommends one to two weeks of normal use, until you are sure the result is stable.
- Preview.
dedcom --purge-quarantinelists the.dedcom-quarantinedirectory of every detected dataset with its file count and total size. It deletes nothing. - Purge.
dedcom --purge-quarantine --yesdeletes those directories: a finalrm -rfof every batch in every dataset, with no selective mode. - Destroy the snapshots separately. The purge does not touch them. List them with
zfs list -t snapshot | grep dedcom-and remove each withzfs destroy. Space is freed only after both steps.
After a hardlink, the target's own owner, permissions, ACLs and xattrs survive only on the original in quarantine, so a purge removes them for good (details).
What the protections do not cover
- Non-ZFS filesystems. The walk and hash work, but there is no snapshot insurance, so applying actions is not recommended.
- The TOCTOU window. Operations act by path, not through an open file descriptor, so a theoretical check-to-act window exists. It is mitigated by the snapshot, the atomic publish, repeated symlink checks and quarantine-based restore; a full
fd+O_NOFOLLOWclosure is deliberately deferred for the single-administrator model the tool targets (details). - Changes between the scan and apply. Revalidation cancels the affected action, but it does not warn you before F11. On large datasets, apply in a maintenance window, when writing workloads are stopped.
- Snapshots or quarantine you removed yourself.
zfs destroyof a snapshot andrm -rfof a quarantine directory are irreversible. - Disk errors. Check
zpool statusand run a scrub; on a damaged pool, none of the tool's protections hold. - Concurrent ZFS operations. Do not run an apply at the same time as a
zfs sendof the same dataset. - A second operator. Two writers on one state directory can corrupt the database.
- Other programs' stores. Backup repositories, Proxmox Backup Server datastores and virtual machine disks need every file unchanged at its own path. A delete or hardlink inside one can break it, so keep such stores outside the scan roots (section 8.9 of the manual).
- Your own scripts. Deduplicating by hand from an
--export-csvlist loses revalidation and snapshot insurance.
Other limits: DedupCommando is Linux-only (x86_64 or aarch64, kernel 3.15 or newer), there is no headless apply, and it typically runs as root. Hardlink and reflink both work within a single dataset, and reflink also needs ZFS 2.3 or newer with block_cloning. See the limitations and what the guardrails do not cover.
Before your first apply: a checklist
- Read chapter 3; the manual calls it mandatory before the first real apply.
- Rehearse on a test pool:
scripts/make-test-pool.shfrom the release bundle creates/testpoolon a file image without touching real disks, andteardown-test-pool.shremoves it (details). - Run as root with
zfsinPATH. Without snapshot privileges, applying is not recommended. - Check that each root lies entirely on ZFS:
df -T <path>should reportzfs(details). - Scan live data with the Idle profile (
Gin the scan configuration cycles to it). - Make sure no other
dedcomis running. - Pick a maintenance window: writing workloads stopped, no
zfs sendof the same datasets. - In the F11 confirmation, read the By type line and the listed paths, which reveal a batch that marked the wrong side of a group, and press S to save the plan as a
.shaudit trail before Y (details). - Start
dedcom --strict-verifyif something else might be editing the files. - Afterward, re-scan and compare the two scans with ScanDiff; anything under Modified is a red flag (details).
Next steps
- Documentation home: install, first scan and guides.
- User manual: every chapter, from installation to troubleshooting.
- Safety, recovery and limitations: the authoritative safety reference.