The Handbook

    Theme
    • Guides
        • Check a system before installing FreeBSD
        • Orient a Linux administrator on FreeBSD
        • Supported FreeBSD releases
        • Choose a FreeBSD documentation and support channel
        • Move files safely without GNU mv -t
        • Update, upgrade, or update packages?
        • Upgrade 14.4 or 15.0 to FreeBSD 15.1
        • Choose packages, ports, or poudriere
        • Choose the quarterly or latest package branch
        • Choose a FreeBSD download or package mirror
        • Make a system setting persistent
        • Configure locale, keyboard, and time zone
        • Configure a serial console for recovery
        • Choose a custom kernel, module, or loader setting
        • Run a Linux binary with the compatibility layer
        • Check desktop and laptop hardware before installation
        • Choose and check a graphics driver
        • Choose Xorg or Wayland
        • Build a maintainable desktop baseline
        • Install and check a desktop browser
        • Check laptop Wi-Fi, power, and suspend
        • Check multimedia readiness
        • Choose and configure a printing stack
        • Run Windows applications with Wine
        • Snapshot and replicate a ZFS dataset
        • Choose a filesystem and storage layout
        • Operate ZFS without losing the recovery path
        • Restore files from a ZFS snapshot
        • Read ZFS pool health and run a scrub
        • Replace a failed device in a ZFS mirror
        • Replicate a ZFS dataset over SSH
        • Change PF safely on a remote host
        • Configure a narrow WireGuard tunnel
        • Plan a FreeBSD home server
        • Choose a mail server or an outgoing relay
        • Publish a network service safely
        • Choose a jail network model
        • Choose native jails or a jail manager
        • Choose a jail or a bhyve virtual machine
        • Establish a FreeBSD security baseline
        • Choose a MAC policy
        • Audit security-relevant activity
        • Start a DTrace performance investigation
    • Integrations
        • Create a first jail with Bastille
        • Compare jail managers and OCI tooling
        • Publish a Bastille service through PF
        • Mount a ZFS dataset in a Bastille jail
        • Update and upgrade Bastille jails
        • Back up and restore a Bastille jail
        • Prepare bhyve and vm-bhyve
        • Choose NFS or Samba for file sharing
        • Choose ZFS backup automation
        • Operate a signed poudriere repository
        • Manage FreeBSD configuration with Ansible or Salt
        • Run Motion with webcamd on FreeBSD
        • Design a reverse proxy, certificates, and monitoring
    • FAQ
      • Troubleshooting
          • Recover an interrupted freebsd-update run
          • Resolve a package repository or ABI mismatch
          • Diagnose the FreeBSD boot path
          • Recover with a ZFS boot environment
          • Diagnose DNS, routing, and firewall paths
          • Diagnose network mbuf exhaustion
          • Bind a service to a low port without running it as root
          • Diagnose audio output or input
          • Diagnose webcamd, cuse, and a webcam
          • Fix USB device permissions without opening every device
      • About this handbook
      • Synopsis
      • Identify the dataset and snapshots
      • Inspect the snapshot directory
      • Restore through a staging path
      • Restore a directory carefully
      • Do not use rollback as a file restore shortcut
      • Primary references

      Restore files from a ZFS snapshot

      Last reviewed
      13 August 2026
      Applies to
      15.1-RELEASE, 15.0-RELEASE, 14.4-RELEASE

      Synopsis #

      The safest response to an accidentally changed or deleted file is usually to copy that file from a snapshot into a separate staging path, inspect it, and then place it deliberately. Rolling back an entire dataset can destroy all changes made after the selected snapshot.

      This procedure assumes that a suitable snapshot already exists. If every copy is on the same damaged or unavailable pool, use an independent backup instead.

      Identify the dataset and snapshots #

      Find the dataset that owns the affected path. If the file was deleted, query its nearest existing parent directory rather than the missing path:

      $ df /srv/data
      $ zfs list -o name,mountpoint
      $ zfs list -t snapshot -o name,creation,used -s creation
      

      Confirm the snapshot time against the event being recovered. The newest snapshot is not automatically the correct source if it already contains the unwanted change.

      Inspect the snapshot directory #

      Check the snapshot directory by addressing it explicitly:

      $ zfs get snapdir tank/data
      $ ls /srv/data/.zfs/snapshot/
      

      If snapdir is hidden, .zfs is not shown by a normal directory listing but can ordinarily be addressed explicitly. Recovery does not require changing the property.

      Inspect the candidate without changing the live file:

      $ stat /srv/data/.zfs/snapshot/hourly-2026-08-13-1400/report.db
      $ if [ -e /srv/data/report.db ]; then cmp /srv/data/report.db /srv/data/.zfs/snapshot/hourly-2026-08-13-1400/report.db; else echo "live file is absent"; fi
      

      cmp returning a difference is expected when the live file was modified. The existence check distinguishes that case from deletion, where there is no live file to compare.

      Restore through a staging path #

      Create a staging directory on a filesystem with enough space, then preserve the candidate’s metadata while copying:

      # mkdir -m 0700 /var/tmp/zfs-restore
      # cp -a /srv/data/.zfs/snapshot/hourly-2026-08-13-1400/report.db /var/tmp/zfs-restore/
      

      Validate the staged file with the application that owns it. A filesystem snapshot is crash-consistent, but a database or other stateful application may require its own recovery or consistency check.

      Stop or quiesce the application when its procedure requires that boundary. Preserve the current file before replacing it, but only when a current file exists:

      # test ! -e /srv/data/report.db || cp -a /srv/data/report.db /var/tmp/zfs-restore/report.db.before-restore
      # install -o appuser -g appgroup -m 0600 /var/tmp/zfs-restore/report.db /srv/data/report.db
      

      The owner, group, and mode are examples. Derive the real values from the service and the prior file; do not copy them blindly.

      Restore a directory carefully #

      Copying a directory from a snapshot does not remove newer files from the live directory. That behavior is often safer than synchronizing deletion. Stage the directory first and compare trees before selecting an application-aware restore command.

      Avoid adding --delete, recursive ownership changes, or a dataset rollback merely to make two trees identical. Each can remove or reclassify data outside the intended recovery set.

      Do not use rollback as a file restore shortcut #

      zfs rollback rewinds the entire dataset. Options that remove newer snapshots or dependent clones expand the loss. Use it only under a separately reviewed recovery plan after newer data has been preserved.

      If many files or the whole dataset must be recovered, create or receive a clone in an alternate namespace and validate it before changing the production mount point.

      Primary references #

      • FreeBSD Handbook: ZFS snapshots
      • zfs-snapshot(8)
      • zfsprops(7)
      • zfs-rollback(8)
      • cp(1)

      Independent documentation. Not affiliated with or endorsed by the FreeBSD Project or the FreeBSD Foundation.

      Report a bug
      • Synopsis
      • Identify the dataset and snapshots
      • Inspect the snapshot directory
      • Restore through a staging path
      • Restore a directory carefully
      • Do not use rollback as a file restore shortcut
      • Primary references