2026/09/17 11:34:46 DEBUG : rclone: Version "v1.76.0-beta.10366.c8d60a67f" starting with parameters ["rclone" "--config" "/tmp/tmp.XXXXXXXXXX/rclone.conf" "bisync" "/tmp/tmp.XXXXXXXXXX/path1" "cry:" "--workdir" "/tmp/tmp.XXXXXXXXXX/workdir" "--ignore-checksum" "--compare" "size,modtime" "--resilient" "--recover" "--color" "NEVER" "-vv"]
2026/09/17 11:34:46 DEBUG : Creating backend with remote "/tmp/tmp.XXXXXXXXXX/path1"
2026/09/17 11:34:46 DEBUG : Using config file from "/tmp/tmp.XXXXXXXXXX/rclone.conf"
2026/09/17 11:34:46 DEBUG : Creating backend with remote "cry:"
2026/09/17 11:34:46 DEBUG : Creating backend with remote "/tmp/tmp.XXXXXXXXXX/path2-raw"
2026/09/17 11:34:46 INFO : Setting --ignore-listing-checksum as neither --checksum nor --compare checksum are set.
2026/09/17 11:34:46 INFO : Bisyncing with Comparison Settings:
{
"Modtime": true,
"Size": true,
"Checksum": false,
"HashType1": 0,
"HashType2": 0,
"NoSlowHash": false,
"SlowHashSyncOnly": false,
"SlowHashDetected": true,
"DownloadHash": false
}
2026/09/17 11:34:46 DEBUG : Lock file created: /tmp/tmp.XXXXXXXXXX/workdir/tmp_tmp.XXXXXXXXXX_path1..cry_.lck
2026/09/17 11:34:46 INFO : Synching Path1 "/tmp/tmp.XXXXXXXXXX/path1/" with Path2 "cry:/"
2026/09/17 11:34:46 DEBUG : updated backup-dir for Path1
2026/09/17 11:34:46 DEBUG : updated backup-dir for Path2
2026/09/17 11:34:46 INFO : Building Path1 and Path2 listings
2026/09/17 11:34:46 DEBUG : *bisync.bisyncRun: starting to march!
2026/09/17 11:34:46 DEBUG : baseline.txt: both path1 and path2
2026/09/17 11:34:46 DEBUG : baseline.txt: is Object
2026/09/17 11:34:46 DEBUG : file.txt: path2 only
2026/09/17 11:34:46 DEBUG : file.txt: is Object
2026/09/17 11:34:46 DEBUG : *bisync.bisyncRun: march completed. err: <nil>
2026/09/17 11:34:46 INFO : Path1 checking for diffs
2026/09/17 11:34:46 DEBUG : 2026-09-17 15:34:46.675463585 +0000 UTC: modification time the same (differ by 0s, within tolerance 1ns)
2026/09/17 11:34:46 INFO : Path2 checking for diffs
2026/09/17 11:34:46 DEBUG : 2026-09-17 15:34:46.675463585 +0000 UTC: modification time the same (differ by 0s, within tolerance 1ns)
2026/09/17 11:34:46 INFO : - Path2 File is new - file.txt
2026/09/17 11:34:46 INFO : Path2: 1 changes: 1 new, 0 modified, 0 deleted
2026/09/17 11:34:46 INFO : Applying changes
2026/09/17 11:34:46 INFO : - Path2 Queue copy to Path1 - /tmp/tmp.XXXXXXXXXX/path1/file.txt
2026/09/17 11:34:46 INFO : - Path2 Do queued copies to - Path1
2026/09/17 11:34:46 DEBUG : updated backup-dir for Path1
2026/09/17 11:34:46 DEBUG : baseline.txt: Excluded (FilesFrom Filter)
2026/09/17 11:34:46 DEBUG : baseline.txt: Excluded
2026/09/17 11:34:46 DEBUG : writing result:
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": {
"Object": {}
},
"Side": "src",
"Err": null
},
"IsWinner": true,
"IsSrc": true,
"IsDst": false,
"Origin": "sync"
}
2026/09/17 11:34:46 DEBUG : writing result:
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": {
"Object": {}
},
"Side": "src",
"Err": null
},
"IsWinner": false,
"IsSrc": false,
"IsDst": true,
"Origin": "sync"
}
2026/09/17 11:34:46 DEBUG : file.txt: Need to transfer - File not found at Destination
2026/09/17 11:34:46 DEBUG : Local file system at /tmp/tmp.XXXXXXXXXX/path1: Waiting for checks to finish
2026/09/17 11:34:46 DEBUG : Local file system at /tmp/tmp.XXXXXXXXXX/path1: Waiting for transfers to finish
2026/09/17 11:34:46 DEBUG : file.txt.25bf15f2.partial: size = 27 OK
2026/09/17 11:34:46 DEBUG : file.txt.25bf15f2.partial: renamed to: file.txt
2026/09/17 11:34:46 INFO : file.txt: Copied (new)
2026/09/17 11:34:46 DEBUG : Waiting for deletions to finish
2026/09/17 11:34:46 DEBUG : failed to marshal input: json: unsupported type: operations.LoggerFn
2026/09/17 11:34:46 DEBUG : b.queueOpt.logger:
2026/09/17 11:34:46 DEBUG : result:
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": null,
"Side": "src",
"Err": null
},
"IsWinner": true,
"IsSrc": true,
"IsDst": false,
"Origin": "sync"
}
2026/09/17 11:34:46 DEBUG : result:
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": null,
"Side": "src",
"Err": null
},
"IsWinner": false,
"IsSrc": false,
"IsDst": true,
"Origin": "sync"
}
2026/09/17 11:34:46 DEBUG : Got 2 results for copy2to1
2026/09/17 11:34:46 DEBUG : - 27 2026-09-17 15:34:46.744463477 +0000 UTC "file.txt"
2026/09/17 11:34:46 DEBUG : - 27 2026-09-17 15:34:46.744463477 +0000 UTC "file.txt"
2026/09/17 11:34:46 DEBUG : syncing empty dirs
2026/09/17 11:34:46 INFO : Updating listings
2026/09/17 11:34:46 DEBUG : updating 2to1
2026/09/17 11:34:46 DEBUG : results:
[
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": null,
"Side": "src",
"Err": null
},
"IsWinner": true,
"IsSrc": true,
"IsDst": false,
"Origin": "sync"
},
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": null,
"Side": "src",
"Err": null
},
"IsWinner": false,
"IsSrc": false,
"IsDst": true,
"Origin": "sync"
}
]
2026/09/17 11:34:46 DEBUG : queue:
{
"file.txt": null
}
2026/09/17 11:34:46 DEBUG : winner: copy to src:
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": null,
"Side": "src",
"Err": null
},
"IsWinner": true,
"IsSrc": true,
"IsDst": false,
"Origin": "sync"
}
2026/09/17 11:34:46 DEBUG : winner: copy to dst:
{
"Src": "cry:/",
"Dst": "",
"Name": "file.txt",
"AltName": "",
"Size": 27,
"Modtime": "2026-09-17T15:34:46.744463477Z",
"Hash": "",
"Flags": "-",
"Sigil": 43,
"Err": null,
"Winner": {
"Obj": null,
"Side": "src",
"Err": null
},
"IsWinner": true,
"IsSrc": true,
"IsDst": false,
"Origin": "sync"
}
2026/09/17 11:34:46 DEBUG : decision: copied to src: file.txt
2026/09/17 11:34:46 DEBUG : decision: copied to dst: file.txt
2026/09/17 11:34:46 DEBUG : updating 1to2
2026/09/17 11:34:46 DEBUG : results:
null
2026/09/17 11:34:46 DEBUG : queue:
{}
2026/09/17 11:34:46 INFO : Validating listings for Path1 "/tmp/tmp.XXXXXXXXXX/path1/" vs Path2 "cry:/"
2026/09/17 11:34:46 DEBUG : 2026-09-17 15:34:46.675463585 +0000 UTC: modification time the same (differ by 0s, within tolerance 1ns)
2026/09/17 11:34:46 DEBUG : 2026-09-17 15:34:46.744463477 +0000 UTC: modification time the same (differ by 0s, within tolerance 1ns)
2026/09/17 11:34:46 DEBUG : Lock file removed: /tmp/tmp.XXXXXXXXXX/workdir/tmp_tmp.XXXXXXXXXX_path1..cry_.lck
2026/09/17 11:34:46 INFO : Bisync successful
Before you start
Associated forum post URL
https://forum.rclone.org/t/46636 (related, not the same report)
What is the problem you are having with rclone?
When Path1 and Path2 have no hash type in common and
--ignore-checksumis set, a file that is present and identical on both sides, but absent from the prior listings, is never added to the listings. It is re-examined on every run and rolled back each time. If that file is later deleted on one side, bisync sees it as a new file on the other side and copies it back, so the delete is silently reverted.Expected: once bisync has confirmed the file is identical on both paths, it is recorded in the listings, and a later delete on one side is propagated to the other.
Actual: the file is logged as
Files are equal! Skipping, thenfailed to check as hash is missingandfiles not equal on recheck, and is left out of the listings on every run. After a delete on Path1, the next run logsPath2 File is newandQueue copy to Path1, and the deleted file is restored.The reproduction below uses a local directory and a crypt remote, so it needs no cloud account. We first hit this between Dropbox and OneDrive, which also share no hash type. There, files in this state built up over time, and deletes of them made by users on one side were reverted.
How a file gets into this state
Any file that is on both sides but missing from the listings, for example:
--conflict-resolve newer, the resolved file is also left out of the listings);Once in this state, the file never leaves it.
Cause
References are to
c8d60a67f.checkconflictsrunsoperations.CheckFnwith bisync'sCheckFn(checkfn.go). With no common hash,CheckFnreturnsnoHash, andfs/operationscounts a size-equal,noHashpair as a match (check.go).deltas.gothen logsFiles are equal! Skippingand adds the file torenameSkipped(deltas.go).modifyListingrechecks everyrenameSkippedfile (listing.go).recheckcallsWhichEqual, which runs the sameCheckFn, getsnoHashagain and returnsfalse(checkfn.go).recheckthen logsfiles not equal on recheckand rolls the file back to the old listing, which does not contain it (listing.go).In short, the same check with the same result is treated as "equal" in
checkconflictsand as "not equal" inrecheck.This only happens when the user has opted out of cryptcheck and
--downloadwith--ignore-checksum(or--size-only), which is whatWhichChecksays those flags are for (checkfn.go). Without them,recheckdownloads both copies and records the file correctly.Why the suggested workarounds don't cover every setup
In forum thread 46636 the retry cycle was diagnosed for a crypt remote, and the suggestions were to drop
--ignore-checksumor to wrap the remote inhasher. Both work, but both need to read the full content of the files involved. For remotes that hold large files (many GB each) and share no hash type, that is the cost--ignore-checksumexists to avoid. What that thread did not identify is that the cycle is not just a harmless retry: it makes one-sided deletes get reverted.Proposed fix
When
WhichEqualgetsnoHashand the user has opted out with--ignore-checksumor--size-only, compare size, plus modtime if--compareincludes it. That is the same comparisoncheckconflictsanddeltasalready used to decide the file was equal. Unknown sizes are never treated as equal. Without the opt-out flags nothing changes, so the default cryptcheck and--downloadbehaviour stays as it is.I have this change with unit tests on a branch. The tests fail without the change and pass with it. The bisync golden tests (
TestBisyncRemoteLocalwith a local-remote2),go vet,golangci-lintandmake quicktestpass, and the reproduction below behaves as expected with it. I'm happy to open a PR if this approach is acceptable, or to rework it if you would prefer something else.rclone version
Operating system
Linux
Which cloud storage system are you using?
Local filesystem and crypt (minimal reproduction). Originally observed between Dropbox and OneDrive.
Output of
rclone config redactedThe command you were trying to run
A log from the command with the
-vvflagLog of the final run (step 4). Temporary paths are replaced with
/tmp/tmp.XXXXXXXXXX.rclone bisync -vv (step 4)