Syncoid not creating bookmark with --no-sync-snap and --create-bookmark

I’m backing up a ZFS dataset (DATASET1) on my NAS to two external USB disks.

  • USB1 (frequent):

    syncoid --delete-target-snapshots /tank/DATASET1 /usbpool-1/DATASET1

    Works perfectly: creates snapshots, replicates incrementally.

  • USB2 (infrequent):
    First backup:

    syncoid --no-sync-snap --create-bookmark --delete-target-snapshots tank/DATASET1 /usbpool-2/DATASET1

    Works fine: does a full send and creates a bookmark.

  • Problem:
    Weeks later, the source snapshot used for USB2 is gone. syncoid uses the bookmark for incremental send but doesn’t create a new bookmark, so future incrementals get stuck.

Is this a bug, or am I missing something?

Have you tried running syncoid with --debug to see if there’s any explanation for why bookmarks aren’t being created?

Also, what syncoid version are you using?

I’m using :

/usr/sbin/syncoid version 2.3.0
(Getopt::Long::GetOptions version 2.54; Perl version 5.38.2)

I’ll try to run it with –debug.
I guess I’ll have to take a snapshot before ? because if I do it now it’ll only say “nothing to sync” ?

You can’t create a bookmark out of thin air. You have to create one based on a snapshot, and you told syncoid not to take a snapshot. So, no bookmark either.

1 Like

So, if syncoid is in --no-sync-snap it will never create a bookmark ?
Event if the run was successful and it now have the most recent snapshot from the source ?

Let me recap what I’m trying to do and what happens :

  • Before the run :
    /tank/DATASET1 have the old bookmark + the most recent snapshot (let’s call it last_snapshot)
    /usbpool-2/DATASET1 have the snapshot matching the old bookmark, nothing else.

  • After the run :
    /usbpool-2/DATASET1 now have last_snapshot too.
    Syncoid was able to incremental send to last_snapshot thanks to the old bookmark.

So, now syncoid have more than thin air, he have last_snapshot on both sides, why is it not creating the bookmark at “last_snapshot” on the source ? doc says --create-bookmark should be used with --no-sync-snap.

My goal is to always be able to incremental send to my infrequent usb backup disk (usbpool-2), from any old bookmark it have in common with the source and to the most recent snapshot on source.

Are there any common snapshots before last_snapshot? If there are, could you delete last_snapshot on the target and try again? It should create the bookmark on last_snapshot, and if it doesn’t I would like to see the debug output to see why it didn’t. Syncoid unfortunately requires a “new latest snapshot” to create and prune bookmarks and does an early exit when there’s nothing to sync.


There is a weird technical reason for syncoid requiring --no-sync-snap when using --create-bookmark. Syncoid doesn’t lookup the guid for sync-snaps and wants --no-sync-snap so that looking up the guid for the latest snapshot doesn’t fail. The guid is used for naming the bookmark in certain scenarios.

Thank you for the help.

Unfortunately, I don’t have a common snapshot on the source BUT I have a bookmark.
Here is the current state of my source (tank) and destination (usbpool-2) :

tank/DATASET1#old_snapshot
tank/DATASET1@last_snapshot

usbpool-2/DATASET1@old_snapshot
usbpool-2/DATASET1@last_snapshot

If I get what you said, I should now :

  1. delete usbpool-2/DATASET1@last_snapshot
  2. rollback usbpool-2/DATASET1 to @old_snapshot
  3. try to sync with --debug.

I’m pretty confident it won’t create a bookmark (it happened first time) but with debug we should indeed see why.

Yes, you should delete usbpool-2/DATASET1@last_snapshot and try again.

Ok, I deleted the last snapshot on the destination and tried the following.

State before syncoid run :

tank/DATASET1#syncoid_NAS_2026-02-14:17:02:09-GMT00:00
tank/DATASET1@syncoid_NAS_2026-02-14:17:44:48-GMT00:00

usbpool-2/nas/DATASET1@syncoid_NAS_2026-02-14:17:02:09-GMT00:00

On the source, you see the bookmark on the “missing” snapshot of 17:02:09
On the source, you see the most recent snapshot of 17:44:48

On the destination (usbpool-2), you see only the snapshot of 17:02:09

Syncoid should incremental sync to the snapshot at 17:44:48 with the help of the bookmark, and then create a bookmark on the source at 17:44:48.

Syncoid run :

tank/DATASET1 → usbpool-2/nas/DATASET1
DEBUG: SSHCMD: ssh     
DEBUG: checking availability of lzop on source...
DEBUG: checking availability of lzop on target...
DEBUG: checking availability of lzop on local machine...
DEBUG: checking availability of mbuffer on source...
DEBUG: checking availability of mbuffer on target...
DEBUG: checking availability of pv on local machine...
DEBUG: checking availability of zfs resume feature on source...
DEBUG: checking availability of zfs resume feature on target...
DEBUG: syncing source tank/DATASET1 to target usbpool-2/nas/DATASET1.
DEBUG: getting current value of syncoid:sync on tank/DATASET1...
DEBUG:  sudo zfs get -H syncoid:sync 'tank/DATASET1'
DEBUG: checking to see if usbpool-2/nas/DATASET1 on  is already in zfs receive using  ps -Ao args= ...
DEBUG: checking to see if target filesystem exists using " sudo zfs get -H name 'usbpool-2/nas/DATASET1' 2>&1 |"...
DEBUG: getting current value of receive_resume_token on usbpool-2/nas/DATASET1...
DEBUG:  sudo zfs get -H receive_resume_token 'usbpool-2/nas/DATASET1'
DEBUG: no receive token found
DEBUG: getting list of snapshots on tank/DATASET1 using  sudo zfs get -Hpd 1 -t snapshot guid,creation 'tank/DATASET1' |...
DEBUG: getting list of snapshots on usbpool-2/nas/DATASET1 using  sudo zfs get -Hpd 1 -t snapshot guid,creation 'usbpool-2/nas/DATASET1' |...
DEBUG: NEWEST SNAPSHOT: syncoid_NAS_2026-02-14:17:44:48-GMT00:00
DEBUG: getting current value of -p used on usbpool-2/nas/DATASET1...
DEBUG:  sudo zfs get -H -p used 'usbpool-2/nas/DATASET1'
DEBUG: getting list of bookmarks on tank/DATASET1 using  sudo zfs get -Hpd 1 -t bookmark guid,creation 'tank/DATASET1' 2>&1 |...
DEBUG: checking to see if usbpool-2/nas/DATASET1 on  is already in zfs receive using  ps -Ao args= ...
INFO: Sending incremental tank/DATASET1#syncoid_NAS_2026-02-14:17:02:09-GMT00:00 ... syncoid_NAS_2026-02-14:17:44:48-GMT00:00 to usbpool-2/nas/DATASET1:
DEBUG: sync size: ~UNKNOWN
DEBUG: sudo zfs send  -i 'tank/DATASET1'#'syncoid_NAS_2026-02-14:17:02:09-GMT00:00' 'tank/DATASET1'@'syncoid_NAS_2026-02-14:17:44:48-GMT00:00' | mbuffer  -q -s 128k -m 16M | pv -p -t -e -r -b -s 0 | sudo zfs receive  -s -F 'usbpool-2/nas/DATASET1' 2>&1
DEBUG: checking to see if usbpool-2/nas/DATASET1 on  is already in zfs receive using  ps -Ao args= ...

Here is the state after the run :

tank/DATASET1#syncoid_NAS_2026-02-14:17:02:09-GMT00:00
tank/DATASET1@syncoid_NAS_2026-02-14:17:44:48-GMT00:00

usbpool-2/nas/DATASET1@syncoid_NAS_2026-02-14:17:02:09-GMT00:00
usbpool-2/nas/DATASET1@syncoid_NAS_2026-02-14:17:44:48-GMT00:00

Incremental send was successful thanks to the bookmark, but syncoid didn’t create (and didn’t try) a bookmark on the source at syncoid_NAS_2026-02-14:17:44:48-GMT00:00

Okay, found out why this is happening… It’s an odd/buggy behaviour in syncoid when you have exactly one snapshot after a bookmark.

It’s caused by this return statement in syncoid.

				if ($matchingsnap eq $newsyncsnap) {
					# edge case: bookmark replication used the latest snapshot
					return 0;
				}

It’s exiting without doing the cleanup and bookmark steps. Looks like it has been reported before:

3 Likes

Thank you for that, @ikabir. I didn’t actually write this particular feature and I’m not familiar with the codebase; I added a comment on that issue to bring it to phreaker0’s attention–I think I remember him being very directly involved in the creation of the bookmark sync feature, and ideally I’d really prefer not to have to dive in from scratch on this one if a contributor is around who’s already familiar with the logic. :slight_smile:

2 Likes

Thank you guys.

I looked at the github issue and this is indeed exactly what I’m experiencing.

  • I can confirm it’s also ignoring --delete-target-snapshots. Snapshot are left on the destination even if not existing on source.

My syncoid use case rely exclusively on bookmarks and keeping as few snapshots as needed on source and destination. Bookmarks allows me to sync multiple external usb disks, more or less frequently :sweat_smile:

Laverne, would you please add that comment to the GitHub issue itself?

Hey @ikabir, is that you who submitted a patch? I greatly appreciate that… but unfortunately, testing the patched version showed that --no-sync-snap and --create-bookmark still don’t work properly. (I left a detailed note at the GH PR itself.)

Ok, it’s done. Even added a link to this post for details :+1:

1 Like

Yup, that’s me who submitted the patch.

1 Like

Laverne, we’ve got this working now in master. You can download just the syncoid script itself directly from here: https://raw.githubusercontent.com/jimsalterjrs/sanoid/refs/heads/master/syncoid

Replace the copy you have now–we usually install in /usr/local/bin/ by default, but if you installed a package from your distro maintainer, they may have made changes–with the version you download from the link above.

The fix will make it into the next release, which’ll probably be sometime in the next month or so. From there, it’ll likely take another two or three months to work its way out to all the major distros, though who knows? You might get lucky and the maintainer for the package in your parrticular distro might be super quick to jump on it, IDK. :slight_smile:

1 Like

I just ran some tests and it works flawlessly.
Sync is done, bookmark is created, old snapshot is pruned.

I originally installed sanoid/syncoid with the package creation method of the installation readme on the github repo (using dpkg-buildpackage). For now I’ve just replaced the file manually but I plan on rebuilding the package once the official release is coming.

Thank you very much to both of you @mercenary_sysadmin and @ikabir !

2 Likes