⚠️ Before submitting, please verify the following: ⚠️
Bug description
Authorship & verification disclaimer. This report was drafted by an AI assistant (Anthropic Claude) working from a customer debug-bundle, with iterative human direction and verification. I — Fokklz — reviewed each claim, ran the suggested commands, and pushed back where things didn't add up; however, my own background in Unicode normalisation, Swift String semantics, and Realm-core internals isn't deep enough for me to independently audit every assertion to the byte level. Treat this as a well-evidenced tip rather than a fully self-audited bug report. I have the complete customer debug bundles, the per-device forensic markdown reports, and the agent-by-agent verification artefacts (including the Swift execution output, the realm-swift → realm-core source trace, the Docker reproduction transcripts, and the JSONL byte-level verification) and am happy to share them privately as a Git repository on request — please reach out on Discord (@Fokklz) or by email (chat@fokklz.dev). I'd rather not publish the raw bundles publicly because they contain server URLs and account identifiers that are obfuscated in this issue but present verbatim in the logs.
TL;DR
On macOS, the file-provider extension's Realm cache is queried with a byte-level == predicate that does not Unicode-normalise. When NSFileProviderManager hands the FPE an NFD-form URL for a path the server stores in NFC (or vice versa), the Realm lookup at FilesDatabaseManager.swift:179 misses, the FPE treats the item as new/conflicted, and the downstream conflict-resolution path issues a server-side DELETE. The main desktop log shows zero entries at Qt severity error|critical|fatal. The C++ sync engine that runs on Windows/Linux ships QString::NormalizationForm_C defences at six boundaries; the Swift FPE that runs on macOS-in-FPE-mode (the default and only supported mode on modern macOS) ships zero.
Affected versions
- Nextcloud Desktop: 33.0.2 (macOS, cocoa), git revision
54f537e35f8bea165d396bdfb55ab0c02408755c, Qt 6.10.2.
- NextcloudKit: 7.2.6 (pinned by
Package.resolved).
- macOS: reproduced on Tahoe 26.2 and 26.4; also seen on Sequoia 15.
- Server: any (the bug is in the client). Customer was on Nextcloud Enterprise 32.0.6.1.
- Auth: webflow / Microsoft-federated OIDC; reproduced on 4 distinct accounts on the same server.
Severity
Critical — silent data loss. No user-facing surfacing of the deletion.
Confirmed deletions (anonymised)
Files DELETEd from the server, confirmed via the FPE's JSONL log. Both rows below were byte-verified — the URL fields in the JSONL alternated between NFD (pre\xcc\x82t) and NFC (pr\xc3\xaat) enumerator events in the minute before the DELETE fired.
| Account |
Deleted item |
DELETE timestamp (CEST) |
Confirmed NFD/NFC alternation in logs? |
| A |
…/MAMCO/AMRLEDER_KBCB_fiche_prêt_1sign_SignPB[47].pdf |
2026-04-20 10:20:54 |
yes — 3 NFD events (pre\xcc\x82t), 11 NFC events (pr\xc3\xaat) for the same ocId 02208123oczue8n54sn9 within 70 s, then DELETE |
| A |
…/MAMCO/AMRLEDER_KBCB_fiche_prêt_1sign_SignPB[75].pdf |
2026-04-20 10:20:50 |
partial — captured logs show NFC enumerator events; NFD form present in upload-time message body |
| A |
…/Constat MAMCO/Arrival/CR_Pasquart_Muster.docx |
2026-04-20 10:15:56 |
no — pure ASCII filename. Listed here because it was also DELETEd in the same window, but it is NOT evidence for the NFC/NFD mechanism. |
| B |
…/AMRLEDER_KBCB_fiche_prêt_1sign_SignPB.pdf |
2026-04-21 09:18:06 |
yes — 2 NFD events, ≥6 NFC events for ocId 02209281oczue8n54sn9 within 51 s, then DELETE |
Verbatim log evidence — byte-level
Bundle selma_pc/all_synced_but_missing_files/File Provider Domains/<UUID-A>/Logs/2026-04-20_09-05-06 (1332).jsonl. The relevant lines (JSONL line numbers, timestamps verbatim, URL byte sequences verified via Python repr().encode()):
Line 650 at 2026.04.20 10:19:44.436 — Set up enumerator. for ocId 02208123oczue8n54sn9, URL bytes contain pre\xcc\x82t (NFD: p r e U+0302 t).
Line 664 at 2026.04.20 10:19:58.328 (14 s later) — Set up enumerator. for the same ocId, URL bytes now contain pr\xc3\xaat (NFC: p r U+00EA t).
Lines 665, 683, 689, 692, 693, 716, 717 — further enumerator setups, all NFC, over the next 70 s.
Line 720 at 2026.04.20 10:20:54.448:
{"category":"Item","date":"2026.04.20 10:20:54.448","details":{"item":"02208123oczue8n54sn9","url":"…/SignPB[47].pdf"},"level":"info","message":"Successfully deleted item."}
Line 724 at 2026.04.20 10:20:55.442 — Read of URL did fail. with NextcloudKit.NKError code 1 for the same path (the file is no longer on the server; PROPFIND 404s).
Same pattern (NFD enumerator events at upload time → NFC enumerator events → single DELETE) confirmed for SignPB.pdf in bundle collection_pc/no_sync_pre_reset/File Provider Domains/<UUID-B>/Logs/2026-04-21_09-04-07 (1234).jsonl.
Throughout both incidents the main desktop log (Nextcloud.log.0) shows zero entries at Qt severity error|critical|fatal:
$ grep -oE '\[ (debug|info|warning|critical|error|fatal) ' nextcloud.log.0 | sort | uniq -c
19865 [ info
192 [ warning
22 [ debug
(Detailed byte-level forensic report at _VERIFICATION_jsonl.md in the source bundle.)
Steps to reproduce
Reproducer (best-effort from observed evidence)
- macOS 14+/15/26, Nextcloud Desktop 33.x in file-provider mode (default on macOS).
- Server contains at least one file at a path whose name has an NFD-encoded diacritic. Engineer it by uploading via a Mac shell:
curl -u user:pass -T file.pdf "https://server/remote.php/dav/files/user/$(printf 'pre\xcc\x82t.pdf')"
- Mount the account in Finder; navigate to the parent directory so the FPE enumerates it.
- Trigger one or more re-enumerations (view-mode switch in Finder, thumbnail generation, Spotlight).
- Watch
~/Library/Group Containers/<TEAM_ID>.com.nextcloud.desktopclient/File Provider Domains/<UUID>/Logs/<date>.jsonl for Successfully deleted item. followed by PROPFIND 404s on the original URL.
(Source of the path: FileManager+FileProviderDomainLogDirectory.swift:23-26 + FileManager+applicationGroupContainer.swift:25.)
Expected behavior
Code archaeology — the defence exists but does not apply on macOS-in-FPE-mode
Important framing: the 33.x macOS client ships two parallel implementations. The C++ sync engine under src/ is what runs on Windows, on Linux, and on macOS in legacy (non-file-provider) mode. The Swift File Provider Extension under shell_integration/MacOSX/ is what runs on macOS in file-provider mode — the default and only supported mode on modern macOS. The C++ engine has Unicode-normalisation defences and always has; the Swift extension does not. On a macOS 33.x install with the file provider active, the C++ defences are dead code; the Swift extension owns every byte the server sees.
The C++ tree (verbatim in v4.0.5 and still present in v33.0.2 — these are NOT what runs on macOS-in-FPE-mode):
| File:line |
Boundary normalised |
| src/libsync/owncloudpropagator.cpp:813 |
case-clash detection. Comment: // Need to normalize to composited form because of QTBUG-39622/QTBUG-55896 |
| src/common/syncjournaldb.cpp:1007 |
every name written to the sync journal DB on macOS |
| src/gui/folderwatcher_mac.cpp:79 |
every macOS FSEvents path |
| src/gui/folder.cpp:222 |
sync folder canonical path (comment: // Workaround QTBUG-55896) |
| src/gui/socketapi/socketapi.cpp:376 |
every line from the socket API |
| src/gui/macOS/fileprovidersocketcontroller.cpp:58 |
every line from the legacy file-provider socket controller |
The Swift File Provider tree:
$ grep -rEn 'precomposed|decomposed|NFC|NFD|canonicalMapping|Normalization' \
shell_integration/MacOSX/NextcloudFileProviderKit/ \
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/ \
--include='*.swift'
(no matches)
(The Objective-C FinderSync.m does call decomposedStringWithCanonicalMapping, but that's a separate overlay-badge subsystem and uses NFD on purpose because Finder hands it NFD paths. It does NOT touch sync data.)
Which files are affected by this bug
…/MAMCO/AMRLEDER_KBCB_fiche_prêt_1sign_SignPB[47].pdf
Operating system
macOS
Which version of the operating system you are running.
Tahoe 26.2 and 26.4
Installation method
Other
Nextcloud Server version
Nextcloud Enterprise 32.0.6.1
Nextcloud Desktop Client version
33.0.2 (macOS, cocoa), git revision 54f537e35f8bea165d396bdfb55ab0c02408755c, Qt 6.10.2.
Did this occur after an update or on a clean installation?
Major version update (i.e. 4.0.0 → 33.0.0)
Are you using the Nextcloud Server Encryption module?
No
Are you using an external user-backend?
Nextcloud Server logs
The affected server is a Hetzner-managed Nextcloud Enterprise tenant; I do not have access to its server-side logs (PHP error log, Apache/nginx access log, audit log, `oc_files_*` table dumps). All evidence in this report is from the macOS client side: the file-provider extension's JSONL logs, the main desktop log, the Realm cache files, the local sync-folder state, and static analysis of the published client + server source.
Additional info
Latent NFD-in-Realm on a healthy device
kvm_pc (a customer device that's working fine) has a Realm whose strings dump contains both NFC and NFD spellings of könnten in the same folder name (25.04. Wenn Stoffe sprechen könnten). This shows that NFD strings can enter the Realm even without an overt failure; the conflict-resolution path doesn't fire on this device — yet.
Open questions (not yet answered by available evidence)
- The exact downstream code path that turns a Realm lookup miss into a server
DELETE. The JSONL log confirms (a) repeated NFC/NFD enumerator alternation, (b) eventual Successfully deleted item. from Item+Delete.swift, but the decision to delete is made somewhere between the enumerator and Item+Delete.swift and a maintainer with FPE source access can trace it directly.
- The
CR_Pasquart_Muster.docx deletion (pure ASCII, no NFC/NFD ambiguity) which occurred in the same minute and same account — listed in the deletions table for transparency, but cannot be attributed to NFC/NFD. It may share a different trigger; suggests there's a secondary issue not characterised by this report.
Cross-links
Bug description
TL;DR
On macOS, the file-provider extension's Realm cache is queried with a byte-level
==predicate that does not Unicode-normalise. WhenNSFileProviderManagerhands the FPE an NFD-form URL for a path the server stores in NFC (or vice versa), the Realm lookup atFilesDatabaseManager.swift:179misses, the FPE treats the item as new/conflicted, and the downstream conflict-resolution path issues a server-sideDELETE. The main desktop log shows zero entries at Qt severityerror|critical|fatal. The C++ sync engine that runs on Windows/Linux shipsQString::NormalizationForm_Cdefences at six boundaries; the Swift FPE that runs on macOS-in-FPE-mode (the default and only supported mode on modern macOS) ships zero.Affected versions
54f537e35f8bea165d396bdfb55ab0c02408755c, Qt 6.10.2.Package.resolved).Severity
Critical — silent data loss. No user-facing surfacing of the deletion.
Confirmed deletions (anonymised)
Files DELETEd from the server, confirmed via the FPE's JSONL log. Both rows below were byte-verified — the URL fields in the JSONL alternated between NFD (
pre\xcc\x82t) and NFC (pr\xc3\xaat) enumerator events in the minute before the DELETE fired.Verbatim log evidence — byte-level
Bundle
selma_pc/all_synced_but_missing_files/File Provider Domains/<UUID-A>/Logs/2026-04-20_09-05-06 (1332).jsonl. The relevant lines (JSONL line numbers, timestamps verbatim, URL byte sequences verified via Pythonrepr().encode()):Line 650 at
2026.04.20 10:19:44.436—Set up enumerator.for ocId02208123oczue8n54sn9, URL bytes containpre\xcc\x82t(NFD:p r e U+0302 t).Line 664 at
2026.04.20 10:19:58.328(14 s later) —Set up enumerator.for the same ocId, URL bytes now containpr\xc3\xaat(NFC:p r U+00EA t).Lines 665, 683, 689, 692, 693, 716, 717 — further enumerator setups, all NFC, over the next 70 s.
Line 720 at
2026.04.20 10:20:54.448:{"category":"Item","date":"2026.04.20 10:20:54.448","details":{"item":"02208123oczue8n54sn9","url":"…/SignPB[47].pdf"},"level":"info","message":"Successfully deleted item."}Line 724 at
2026.04.20 10:20:55.442—Read of URL did fail.withNextcloudKit.NKError code 1for the same path (the file is no longer on the server; PROPFIND 404s).Same pattern (NFD enumerator events at upload time → NFC enumerator events → single DELETE) confirmed for
SignPB.pdfin bundlecollection_pc/no_sync_pre_reset/File Provider Domains/<UUID-B>/Logs/2026-04-21_09-04-07 (1234).jsonl.Throughout both incidents the main desktop log (
Nextcloud.log.0) shows zero entries at Qt severityerror|critical|fatal:(Detailed byte-level forensic report at
_VERIFICATION_jsonl.mdin the source bundle.)Steps to reproduce
Reproducer (best-effort from observed evidence)
curl -u user:pass -T file.pdf "https://server/remote.php/dav/files/user/$(printf 'pre\xcc\x82t.pdf')"~/Library/Group Containers/<TEAM_ID>.com.nextcloud.desktopclient/File Provider Domains/<UUID>/Logs/<date>.jsonlforSuccessfully deleted item.followed by PROPFIND 404s on the original URL.(Source of the path:
FileManager+FileProviderDomainLogDirectory.swift:23-26+FileManager+applicationGroupContainer.swift:25.)Expected behavior
Code archaeology — the defence exists but does not apply on macOS-in-FPE-mode
Important framing: the 33.x macOS client ships two parallel implementations. The C++ sync engine under
src/is what runs on Windows, on Linux, and on macOS in legacy (non-file-provider) mode. The Swift File Provider Extension undershell_integration/MacOSX/is what runs on macOS in file-provider mode — the default and only supported mode on modern macOS. The C++ engine has Unicode-normalisation defences and always has; the Swift extension does not. On a macOS 33.x install with the file provider active, the C++ defences are dead code; the Swift extension owns every byte the server sees.The C++ tree (verbatim in
v4.0.5and still present inv33.0.2— these are NOT what runs on macOS-in-FPE-mode):The Swift File Provider tree:
(The Objective-C
FinderSync.mdoes calldecomposedStringWithCanonicalMapping, but that's a separate overlay-badge subsystem and uses NFD on purpose because Finder hands it NFD paths. It does NOT touch sync data.)Which files are affected by this bug
…/MAMCO/AMRLEDER_KBCB_fiche_prêt_1sign_SignPB[47].pdf
Operating system
macOS
Which version of the operating system you are running.
Tahoe 26.2 and 26.4
Installation method
Other
Nextcloud Server version
Nextcloud Enterprise 32.0.6.1
Nextcloud Desktop Client version
33.0.2 (macOS, cocoa), git revision
54f537e35f8bea165d396bdfb55ab0c02408755c, Qt 6.10.2.Did this occur after an update or on a clean installation?
Major version update (i.e. 4.0.0 → 33.0.0)
Are you using the Nextcloud Server Encryption module?
No
Are you using an external user-backend?
Nextcloud Server logs
Additional info
Latent NFD-in-Realm on a healthy device
kvm_pc(a customer device that's working fine) has a Realm whosestringsdump contains both NFC and NFD spellings ofkönntenin the same folder name (25.04. Wenn Stoffe sprechen könnten). This shows that NFD strings can enter the Realm even without an overt failure; the conflict-resolution path doesn't fire on this device — yet.Open questions (not yet answered by available evidence)
DELETE. The JSONL log confirms (a) repeated NFC/NFD enumerator alternation, (b) eventualSuccessfully deleted item.fromItem+Delete.swift, but the decision to delete is made somewhere between the enumerator andItem+Delete.swiftand a maintainer with FPE source access can trace it directly.CR_Pasquart_Muster.docxdeletion (pure ASCII, no NFC/NFD ambiguity) which occurred in the same minute and same account — listed in the deletions table for transparency, but cannot be attributed to NFC/NFD. It may share a different trigger; suggests there's a secondary issue not characterised by this report.Cross-links
macOS VFS: Nextcloud keeps adding files to trash bin after emptying bin) — symptoms consistent with a shared root cause.