When Both Sides Edit: Conflicts
The question every sync tool eventually has to answer: the same file, changed two ways, on two machines that couldn't see each other. The cloud answer is a server deciding, quietly, whose copy is "the" file. Syncthing has no server and makes a plainer bargain: one version wins the name, the other is kept whole beside it, and a human sorts it out.
The lab manufactures the situation honestly. Versioning is switched off first (so nothing but the conflict machinery can catch the loser), a front-page file is synced to both sides, and then juniper is shut down through the API:
$ curl -s -X POST -H "X-API-Key: $KEY" http://127.0.0.1:8395/rest/system/shutdown
{"ok": "shutting down"}
While juniper is down, its copy is edited — the fair moves to the hall. Two seconds later, willow's copy is edited the other way — the fair stays on the green. (The pause matters: the file edited first carries the older modification time, and that is about to be the whole story.) Juniper starts again, the two devices compare notes, and:
$ ls share-a share-b
share-a:
…
front-page.md
front-page.sync-conflict-20261021-025700-VDKRCPU.md
…
share-b:
…
front-page.md
front-page.sync-conflict-20261021-025700-VDKRCPU.md
…
$ sha256sum share-a/front-page.md share-b/front-page.md
e9f4ff7f3bc5b89e7ea4aa60a8091874022e66639d0eba4bf9c8bda7c41dfb3e share-a/front-page.md
e9f4ff7f3bc5b89e7ea4aa60a8091874022e66639d0eba4bf9c8bda7c41dfb3e share-b/front-page.md
Reading the wreckage
Under its proper name, on both machines, the winning version:
# Front page: fair stays on the green
The autumn fair stays on the green this year;
the forecast has improved after all. (A's edit)
And in the long-named file, also on both machines, the loser, complete:
# Front page: fair moves to the hall
The autumn fair moves to the village hall this
year because of the weather forecast. (B's edit)
Three rules, two of them visible in the capture and the third from Syncthing's documentation:
- The version with the newer modification
time wins the name. Willow's edit was made
second, so willow's text is
front-page.mdeverywhere. Juniper's older edit lost. Had the times tied, the documentation says the tie is broken by comparing device IDs — a coin flip neither editor can see coming, and one more reason the loser is never deleted. - The loser becomes a conflict file, named
<file>.sync-conflict-<date>-<time>-<device>.<ext>— here20261021-025700andVDKRCPU, the winning device's short ID as recorded in this capture. The name is ugly on purpose: it cannot be mistaken for the real file, and it sorts and searches well. - The conflict file is an ordinary file. It synced to willow the moment it was created on juniper, which is why both listings show it. Nothing hides it, nothing resolves it, and nothing deletes it: renaming, merging, or removing it is a human's job, and whatever the human does then syncs as normal.
One neighbouring case the lab did not run, stated from the documentation so it doesn't surprise you in the wild: if one side edits a file while the other side deletes it, the edit wins and the file is resurrected on the deleting device — no conflict copy. Deletion loses to content.
The honest cost
A conflict file is Syncthing declining to
guess which of your sentences mattered. Tools
that merge or pick silently are smoother right
up to the paragraph they silently lose. The
discipline this asks of you is small and
unavoidable: when a .sync-conflict name
appears, open both files, keep what you need
under the real name, and delete the conflict
copy yourself. Chapter 10 treats a folder full
of them as the symptom it is — usually two
devices habitually editing the same file while
apart, which is a workflow asking to be split.
Check: the filename is the tell. Search a
shared folder for sync-conflict names —
any hit is a past moment when two machines
disagreed and both were kept. If the real file
and the conflict copy have since drifted into
two different documents, you have found the
other reason this chapter exists: the conflict
copy is a file too, and it ages like one.