I have two machines, "sender" and "receiver".

Sender runs the following command each night:

zfs send -i bpool/backups@2018-09-04 bpool/backups@2018-09-05 | ssh receiver /sbin/zfs receive bpool/backups

The sends the latest of bpool/backups from sender to receiver. (Dates are automatically generated each night.)

If someone (on receiver) does as little as:

cd /bpool/backups

it breaks the nightly backup job, with the following error:

root@sender:~# zfs send -i bpool/backups@2018-09-04 bpool/backups@2018-09-05 | ssh recevier /sbin/zfs receive bpool/backups
cannot receive incremental stream: destination bpool/backups has been modified
since most recent snapshot
warning: cannot send 'bpool/backups@2018-09-04': Broken pipe

(I assume this is because of updated atimes, or similar.)

How can I stop this from happening? (If I made receiver:/bpool/backups read-only how would the receive work?)

4 Answers 4


You can indeed set your target dataset to be readonly (by setting the zfs property readonly=on directly on the target dataset or one of its parents). This will not hinder you from receiving newer snapshots, because readonly for a dataset only means, that you cannot make changes to the files (, directories and attributes) inside.

This is different from setting readonly=on when you import a pool. With a pool readonly means, that IO cannot write anything to the pool's backend.

I for one am not quite happy with the accepted answer, because simply by principle, noone should make any changes whatsoever on a dataset that is meant to only receive anyway.

Another reason why I'm against the -F switch is, that when you receive incremental snapshot data (zfs send -i data@older-snap data@newer-snap), then the -F switch also results in snapshots being deleted from the backup dataset that do not also exist in the source dataset (albeit only newer ones). It is always good to design your services so that they fail (and report errors) when they encounter something unexpected (instead of just ignoring errors).

For a backup pool/dataset, you might also want to set atime=off, because that too contradicts its purpose.

Edit: Ah and one should add, that you can keep these properties set only on the receiving dataset (which would be overwritten in case they were set directly in the source dataset) by using zfs receive -o atime=off -o readonly=on

  • this is the right answer Commented Apr 14, 2023 at 8:37

zfs recv -F will force the receiving dataset to roll back to the previous received snapshot. Turning off atime will only address the issue of people examining the files on the backup, but if there are any other changes, you'll want to use the -F flag instead.

  • Notice though that the docs say that -F will destroy snapshots and file systems that do not exist on the sending side. That will possibly include older ones.
    – lucidbrot
    Commented Mar 5, 2022 at 13:52

Turning off access time update should be enough:

zfs set atime=off bpool/backup
  • 1
    Does the receiving dataset even have to be mounted? Commented Sep 6, 2018 at 14:20

Personnally I prefer to directly mount the snapshots as read-only, that way we don't even modify snapshots by construction.

If you are on an encrypted dataset, first run the following commands to load the keys:

$ sudo zfs load-key -a

Then just mount it, for example as follows (no need for -o ro options):

$ mkdir /tmp/zp
$ sudo mount -t zfs zpool_my_passport/backup/2020_Dell_laptop@2021_01_05_-_test_update /tmp/zp/

But if a modification happens, indeed zfs recv -F is really practical (I'm just a bit afraid to have data losts with -F so that's why I prefer this method).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .