Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

ZFS BuddyBackup plugin guide

Featured Replies

Overview

ZFS BuddyBackup is an Unraid plugin designed to make ZFS snapshot maintenance, local pool replication, and offsite backups between two Unraid servers (or between Unraid and generic OpenZFS systems) simple, automated, and secure:

  • Raw Encrypted Transfers: Remote transfers use raw ZFS send (zfs send -w). Data remains encrypted in transit and at rest on the remote server without requiring the destination host to possess your encryption keys (zero-knowledge backup destination).

  • Least-Privilege Security: Remote connections run as a restricted non-root buddybackup user locked to an SSH forced-command allowlist (restrict_zfs). Interactive shell access and arbitrary commands are blocked.

  • Remote Immutability: Destructive commands (zfs destroy, zfs rollback) are strictly blocked on the receiver to protect against remote compromises and ransomware.

Disclaimer: I take no responsibility for data loss or damage caused by using this plugin. Please review the open-source code and report any bugs or suggestions on GitHub or the Unraid forum.

You can find the source code here: https://github.com/Piratkopia13/unraid-buddybackup.

Prerequisites & Installation

  1. Unraid Version: Unraid 6.12.0 or newer with OpenZFS.

  2. Installation: Install ZFS BuddyBackup via the Unraid Community Applications (Apps) tab.

  3. Encryption: By default, remote backups require an encrypted source ZFS dataset. If you must back up unencrypted datasets remotely over a trusted private network, enable Allow unencrypted remote in Advanced Settings.

  4. Network Connection: Connect remote servers over a secure network (e.g. Tailscale, WireGuard, or private LAN). Avoid exposing SSH directly to the public internet.

Interface Walkthrough

In the Unraid WebGUI, access the plugin under Tools → ZFS Buddy Backup.

The interface is organized into five tabs:

  1. Backup and restore

  2. Snapshot creation and pruning

  3. Buddy's Backups

  4. Advanced Settings

  5. Log

(A live status panel is also available on the main Unraid Dashboard).

1. Backup and restore

The main command center for configuring, monitoring, and restoring backups.

Backup and restore Overview

Your SSH Public Key

Send your SSH public key to your buddy to add under their Buddy's Backups page (or use it when running the setup helper on a generic receiver).

Backup Tasks

Each configured backup task displays:

  • Status: Status indicators for Healthy, Triggered by snapshot, Warning (overdue), Alert (critical overdue), Failed (last run error), or Disabled.

  • Route & Telemetry: Source dataset pool/dataset → destination, last run timestamp, destination size, cron schedule, and snapshot trigger badges.

  • Alert Banners: Displays failure date, error details, and log link if a task is overdue or failed.

Backup Task Details

Source Settings
  • Enable on cron schedule: Enables scheduled automated runs.

  • ZFS dataset to backup: Local dataset to replicate (encrypted datasets by default).

  • Backup child datasets: Recursively replicate child datasets and snapshots.

  • Skip parent dataset: Replicate only child datasets, skipping the root parent dataset (useful when replicating container datasets or pools without duplicating the parent).

  • Cron schedule: Cron expression defining when the backup runs (default: 0 0 * * * for midnight).

Destination Settings
  1. Remote (BuddyBackup) (Unraid → Unraid):

    • Buddy's hostname or IP: Remote Unraid VPN/LAN IP.

    • Test connection: Verifies SSH connectivity and command restriction (restrict_zfs).

    • Destination dataset: Must start with your buddy's configured parent dataset, followed by a child dataset name (e.g. tank/backups/buddy/my-data).

  2. Remote (generic ZFS host) (Unraid → TrueNAS SCALE / Proxmox VE / Linux):

    • Buddy's hostname or IP: Remote host IP or hostname.

    • Remote username & SSH port: SSH user (default: buddybackup) and port (default: 22).

    • Destination dataset: Target dataset path on remote host (e.g. tank/backups/unraid/appdata).

    • Remote host one-time setup: Generates the root command to configure the remote host.

    • Test connection: Verifies SSH connectivity, ZFS version, dataset existence, encryption support, resume tokens, and delegated permissions.

Generic ZFS Host Setup Helper

  1. Local (Pool-to-Pool on the same Unraid server):

    • Destination dataset: Local target dataset (autocomplete provided).

    • Write Protection: Local destination datasets are automatically set to readonly=on upon sync to prevent accidental tampering and ransomware corruption.

Task Actions
  • Send backup now: Runs preflight checks (verifying source dataset, encryption, and snapshots). If no snapshots exist yet, prompts you to create one and send immediately.

  • Create fresh snapshot and send now: Takes an immediate local snapshot (autosnap_YYYY-MM-DD_HH:MM:SS_hourly) and starts replication.

  • Restore data from destination: Opens the Restore Snapshot Wizard.

Restore Snapshot Wizard

Restore Snapshot Wizard

  1. Select a snapshot from the dropdown (grouped by dataset).

  2. Choose a restore mode:

    • Restore selected snapshot: Restores the single selected snapshot.

    • Restore all snapshots in selected dataset: Restores the complete snapshot history for that dataset.

  3. Choose the destination:

    • New dataset: Restores to a new local dataset name.

    • Restore to selected: Restores into an existing local dataset (requires at least one common snapshot).

  4. Live progress streams in a terminal; restores continue in the background if closed.


2. Snapshot creation and pruning

Automated snapshot creation and retention policies powered by Sanoid.

Snapshot Creation and Pruning

  • Dataset & Recursive: Dataset to snapshot, with optional recursion.

  • Create snapshots automatically (autosnap) & Prune snapshots automatically (autoprune): Toggle automated snapshot creation and retention pruning.

  • Snapshot retention: Number of snapshots to retain for Hourly, Daily, Weekly, Monthly, and Yearly intervals.

  • Trigger backup after snapshot: Select a backup task to run immediately whenever Sanoid creates a new snapshot of this dataset.

Note

Sanoid runs automatically every 15 minutes (*/15 * * * *) via cron whenever snapshot or incoming buddy tasks are enabled.


3. Buddy's Backups (Receiving Backups)

Configures your Unraid server to receive incoming backups from buddies or external systems. You can add multiple buddies with independent public keys, datasets, and retention policies.

Buddy's Backups Receiver Configuration

  • Buddy Name: Friendly label to identify this buddy (e.g. Alex (Offsite), Bob (TrueNAS)).

  • Enable: Allow incoming connections for this buddy.

  • Buddy's SSH public key: Paste buddy's public SSH key (restricted to restrict_zfs in authorized_keys).

  • Destination parent dataset: Dedicated sub-dataset where your buddy's backups live (e.g. disk1/buddy_backups).

    • Must be a dedicated sub-dataset (contains a /), not a bare root disk or pool. Overlapping datasets across buddies are disallowed for isolation.

    • Automatically configured with readonly=on, mountpoint=none, setuid=off, and exec=off to keep incoming backups immutable and isolated from Unraid's VFS tree.

    • Restoring via the Restore Wizard creates writable datasets. For an emergency in-place failover:

      zfs set readonly=off <pool/dataset>
      zfs inherit mountpoint <pool/dataset>
  • Snapshot retention: Local Sanoid policy for how long to keep your buddy's snapshots (Hourly, Daily, Weekly, Monthly, Yearly).

Note

Receiving from TrueNAS SCALE or Proxmox VE?
Sudo mode is not supported on Unraid (restrict_zfs blocks sudo). In TrueNAS, keep Use Sudo For ZFS Commands unchecked and Snapshot Retention Policy set to None (destructive zfs destroy is rejected on Unraid; Unraid Sanoid manages retention locally).


4. Advanced Settings

Fine-tune daemon settings, alert thresholds, and security overrides.

Advanced Settings

General
  • Use UTC timezone (default: No): Uses UTC timestamps (TZ=UTC) for snapshot creation, Sanoid cron, and manual snapshot naming. Useful to align timestamps between servers in different timezones.

Dashboard Panel & Alert Thresholds

Configure when status indicators turn warning or alert on the dashboard and task cards (leave empty or 0 to disable):

  • Backup warning (days, default: 7): Mark outgoing backup as warning if inactive for this many days.

  • Backup alert (days, default: 30): Mark outgoing backup as alert if inactive for this many days.

  • Buddy's backup warning (days, default: 7): Mark incoming backup as warning if inactive for this many days.

  • Buddy's backup alert (days, default: 30): Mark incoming backup as alert if inactive for this many days.

Security Overrides (Danger Zone)
  • Allow unencrypted remote (default: No): Overrides the requirement for remote datasets to be encrypted (zfs send -w). Enables sending unencrypted datasets over trusted networks.

Warning

Only enable Allow unencrypted remote over trusted private networks (e.g. WireGuard/Tailscale) if you understand the risks. Data is transferred and stored without native ZFS encryption.


5. Log

Displays live output from /var/log/buddybackup.log, streaming updates every 2 seconds. Useful for monitoring active replications and diagnosing connection or delegation issues.

Replication Log Viewer


6. Unraid Dashboard Integration

A dashboard widget summarizing your backup health at a glance:

Unraid Dashboard Integration

  • Header: Live aggregate counts (X backup(s), Y autosnap, Z autoprune, Incoming active).

  • Table Columns:

    • Source: Source dataset or buddy label.

    • Destination: Target host and dataset path.

    • Status: Status indicator with schedule and trigger badges.

    • Last run: Human-readable relative timestamp (e.g. Today, 06:00).

    • Size: Used storage on the destination.


For a deep-dive in how to work with generic ZFS hosts as either receiver or sender, see the user guide on github: https://github.com/Piratkopia13/unraid-buddybackup/blob/main/docs/USER_GUIDE.md#generic-zfs-hosts-deep-dive

Happy backups!

Edited by Pirat

  • Replies 73
  • Views 14.9k
  • Created
  • Last Reply

Top Posters In This Topic

Most Popular Posts

  • Yeah it's a really neat plugin that is sorely missing from the unraid experience.    Wishlist/Wantlist:   - To run the automatic snapshot feature on a cron schedule  - Ability

  • Different people have different setups and different needs for backup solutions. I know there are different solutions circulating already for Unraid and ZFS, but  many use root ssh connections to func

  • @MowMdown I just pushed an update that fixes the bug you found. I don't think Unraid allows auto updates of manually installed plugins, so you might have to uninstall it and then re-install it wi

Posted Images

  • Author

Different people have different setups and different needs for backup solutions. I know there are different solutions circulating already for Unraid and ZFS, but  many use root ssh connections to function which is not okay at all in my opinion. This plugin aims to solve that, among other things.

 

If you use ZFS and need a backup solution between two Unraid servers that this plugin does not satisfy, I would be interested to hear about your setup and why this plugin doesn't work for you. I might not be able to solve the problems, but hearing different needs could help guide the direction I take this plugin in the future.

 

For reference, since I wrote this plugin to be my main backup solution, the following is my setup:

I have a ZFS pool consisting of some nvme ssds where I store all appdata, VM disks etc. In my array I have a couple of HDDs of which one is formatted with ZFS. I perform daily snapshots on the nvme pool and sync those snapshots to the ZFS disk in the array. Every week I sync the same snapshots to a buddy's Unraid server. This follows the classic 3-2-1 backup rule - have three copies of your data, stored on two different types of media, with one copy kept offsite.

The example images in the guide above show how I have this setup in the plugin. It fills all my backup needs, from snapshot creation and pruning, to local backups, to remote offsite backup and restore.

Edited by Pirat
added my own backup setup for reference

  • 2 weeks later...

Question/Possible Bug? Below is how I configured this to work, I want local backups from Source: cache/appdata to Dest: zfs/snapshots/appdata, so far so good. However your log is telling me something that doesn't quite add up with what Im doing. Clearly I want cache/appdata under the snapshots creation and pruning section otherwise there would be nothing to snapshot create/prune. Then for the backup/restore I clearly want to RESTORE my snapshots from the destination (zfs/snapshots/appdata)

 

If anything, maybe break the Backup/Restore function into two separate functions. As it is right now, If the user doesn't know any better, assuming most people who might use this are zfs noobs, there isn't any explicit "restore" options to choose. (which is why I think your log message is throwing me a warning because it thinks Im trying to backup a dataset to itself)

 

Also what is the cron schedule for taking the automatic snapshots? I prefer to run my schedule every hour but there's no option for that for snapshot creation? It says automatic but how do you run it and how often does it run?

 

image.thumb.png.c96d1ac372943a2549dbde89628a2af9.png

image.thumb.png.f24d326bf14841eff910fcd6ad9a488c.png

image.thumb.png.99d3f954cc67d98dddd7b16923601438.png

 

 

Edited by MowMdown

  • Author

@MowMdown

That warning is very much a bug. It's referring to destination in the "buddys backups" section, which you haven't even set. So it's some logic error, I'll get it fixed. Thanks for reporting! 

 

A button for restoring exists, but is currently available only when the destination is remote, as offsite backups was the focus of this plugin. That said, I might add a restore wizard for local backups in the future as well to make that part easier!

Yeah it's a really neat plugin that is sorely missing from the unraid experience. 

 

Wishlist/Wantlist:

 

- To run the automatic snapshot feature on a cron schedule 

- Ability to restore snapshots from local destination (host machine)


Many of us keep a local copy of snapshots on an parity protected array disk, being able to restore from that would be nice.

 

Thanks for sharing the plugin

  • Author

@MowMdown

I just pushed an update that fixes the bug you found. I don't think Unraid allows auto updates of manually installed plugins, so you might have to uninstall it and then re-install it with the link from the first post. Your backup configs will be saved!

The title of your plugin is clear, but since this is the first attempt I have seen to make a plugin for buddy backup, is there any hope that BTRFS could be supported in the future as well? The much higher RAM requirements for ZFS and the risk of data-loss if not using a UPS to protect the RAM led me to using a BTRFS array for my setup among others. BTRFS supports snapshots as well, so I would hope it could become a target for this plugin as well in time.

  • Author

First of all, to clear up possible confusion, ZFS uses the ARC (adaptive replacement cache) to speed up read operations. All write operations are fully protected in case of a power loss. Furthermore, as the name implies, the size of the ARC is adaptive depending on the available system memory. 

On the opposite, as far as I know, btrfs still has the known "write hole" issue in raid5/6 arrays which can cause undetectable data loss on a power loss. That's actually one of the reasons I switched from btrfs to zfs 😁

 

Regarding adding support for btrfs snapshots, I'm definitely not against it! I will put it in the backlog, but my time is limited so don't expect anything soon. 

Really nice plugin but I have problem, I did set up Snapshot creation and pruning mostly like you shown in screenshot in section "Snapshot creation and pruning" but no snapshot are created. I want to backup localy, do I have to setup manual cron to run config for sanoid?

 

image.thumb.png.e678e8da43a7b259d20449d4ae5d4f32.png

Edited by adamzetpl

  • Author

@adamzetpl

You just found another bug! For some reason I put the sanoid cron to be enabled only if you have enabled the  "Buddys Backups" section. You can enable that for now and that should set up the automatic sanoid cron for you. I will get it fixed in the next version! 

32 minutes ago, Pirat said:

@adamzetpl

You just found another bug! For some reason I put the sanoid cron to be enabled only if you have enabled the  "Buddys Backups" section. You can enable that for now and that should set up the automatic sanoid cron for you. I will get it fixed in the next version! 

Now cron is working but I get in log:

FATAL: cannot load /boot/config/plugins/buddybackup/sanoid.conf - please create a valid local config file before running sanoid! at /usr/local/emhttp/plugins/buddybackup/deps/sanoid line 917.

 

  • Author
7 minutes ago, adamzetpl said:

Now cron is working but I get in log:

FATAL: cannot load /boot/config/plugins/buddybackup/sanoid.conf - please create a valid local config file before running sanoid! at /usr/local/emhttp/plugins/buddybackup/deps/sanoid line 917.

 

That's odd. Could you send the output of
cat /boot/config/plugins/buddybackup/sanoid.conf

as well as 

cat /boot/config/plugins/buddybackup/snapshots.cfg

 

The sanoid.conf is created from the snapshots.cfg when you modify anything in the snapshot creation/pruning setting section.

You can also manually force the update of sanoid.conf by running:

/usr/local/emhttp/plugins/buddybackup/scripts/rc.buddybackup.php update_sanoid_conf

but that really shouldn't be necessary.

[]
    hourly = 0
    daily = 7
    weekly = 4
    monthly = 3
    yearly = 0
    autosnap = no
    autoprune = yes
    recursive = yes

[cache/appdata]
    recursive = yes
    autosnap = yes
    autoprune = yes
    hourly = 0
    monthly = 2
    daily = 7
    yearly = 0
    weekly = 4
[7bef260e]
dataset="cache/appdata"
recursive="yes"
autosnap="yes"
autoprune="yes"
hourly="0"
monthly="2"
daily="7"
yearly="0"
weekly="4"
trigger="no"

 

  • Author

@adamzetpl

Ah. I'm guessing sanoid doesnt like that empty first section (the []). It's there because you have enabled Buddy's Backup section, but not selected a destination dataset.

Try also setting any destination dataset in that section and see if sanoid starts working. (note that it will autoprune snapshots in the selected dataset)

I will get both these bugs fixes asap.

Edited by Pirat

Now everything is OK

  • Author

@adamzetpl

I just pushed a new version that fixes the issues you found! After updating, you can disable the buddy's backup section again if you aren't using it.

Thanks for letting me know of the issues! 🏆

Edited by Pirat

I have little more feedback, i removed plugin (deleted files from boot, restart unraid). After installing fresh I need to enable Buddy's Backups for cron snapshot to be created (after this I can disable it), additional error I get after Backup and restore job runs: "Local backup failed. Error code 2."
It seems that everything is running fine, snapshot are created, dataset is mirrored but I get constant error "Local backup failed. Error code 2.".

  • Author

I recommend installing the plugin from the apps tab, and updating the plugin should work. No need to manually uninstall/reinstall any more. 

 

Could you confirm with version of the plugin you are on? 

Also, do you get any other print in the log other than "Local backup failed. Error code 2."? This means that syncoid did not exit cleanly and the actual error should have been printed above. 

You could also try running the backup from the button in settings and see if you get anything more printed in the popup. 

Verision of plugin 2025.02.23 its from CA not manual install.

 

Running backup..
CRITICAL ERROR: 
Target backup_hdd/zfs_backup/appdata_backup exists but has no snapshots matching with cache/appdata!
Replication to target would require destroying existing
target. Cowardly refusing to destroy your existing target.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:10_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:18_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:26_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:23_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:01_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:16_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:14_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:01_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:07_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:06_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:26_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:08_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:29_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:11_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:15:19_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:20_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:04_daily on target. Nothing to do, not syncing.
INFO: no snapshots on source newer than autosnap_2025-02-24_00:30:15_daily on target. Nothing to do, not syncing.
Local backup failed. Error code 2.
[[rc.buddybackup finished]]

 

  • Author

I will investigate the cron snapshot not being created on a fresh install, that shouldn't happen 🤔

 

Your syncoid error there looks to me like the destination parent dataset (cache/appdata) doesn't have any snapshots, but all the child datasets do. I think this could happen if you for instance created the destination dataset yourself instead of letting syncoid create it on the first backup. Please verify if that is the case for you, and if it is the easiest way to solve that is manually syncing the oldest snapshot for the parent dataset with `zfs send cache/appdata@name-of-oldest-snapshot | zfs recv -F backup_hdd/zfs_backup/appdata_backup`. Note the -F flag which is destructive and will rollback the destination to match the source.

You could also change the backup destination to a new dataset that doesn't exist and re-run the full backup.

I did run full backup and now everything is OK. Thank you.

  • Author

Just pushed version 2025.03.02 with support for restoring snapshots from local backups

@MowMdown

Awesome, ill check it out

I have another question, when using local backup so "Backup and restore" part of plugin every snapshots ever created is copied, is there a way to Prune snapshots like "Snapshot creation and pruning"? Local backup is growing fast with all snapshots (even those that were prune in "Snapshot creation and pruning").

  • Author

You can just add the local destination dataset to the snapshot creation and pruning section. Disable autosnap, enable autoprune and select retention. 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.