Skip to content

[Bug]: Sync engine livelocks at 100% CPU (zero network/disk I/O) when synced tree contains a per-directory .sync-exclude.lst in VFS mode (Windows/wincfapi) #10301

Description

@Edge324

⚠️ Before submitting, please verify the following: ⚠️

Bug description

On Windows with virtual files (wincfapi), if the synced tree contains a per-directory .sync-exclude.lst, the client hangs forever on every sync run except the very first one after adding the folder:

  • The FIRST sync after adding the folder completes normally (placeholders created).
  • EVERY SUBSEQUENT sync run livelocks: one thread spins at 100% of a single core with ZERO network connections and ZERO disk I/O (verified via perf counters). The --logdebug log freezes mid-discovery of top-level items and never grows again (tested 40+ minutes). The GUI stays "Responding" but sync never progresses. Explorer operations on the sync root fail with "The cloud operation was not completed before the time-out period expired".

The difference between run 1 and run 2+ is that after run 1 the per-directory .sync-exclude.lst exists locally only as a dehydrated online-only placeholder (attributes Offline | RecallOnDataAccess, 0 bytes on disk). Working hypothesis: during discovery the engine must READ that exclude file to build exclusion rules; reading requires hydration; hydration can only be serviced by the same (currently busy) sync engine → self-livelock.

Evidence collected:

  1. Stack sampling of the hot thread (SuspendThread → GetThreadContext → resolve RIP/stack to modules), consistent across samples and across process restarts:
    RIP: ntdll.dll+0x160134 / +0x160294 / +0x1603F4 (heap functions)
    Stack: KERNELBASE.dll → Qt6Core.dll+0x22D3E5 / +0x14C200 / +0x235005 → ucrtbase.dll+0x12D7B → nextcloud_csync.dll+0xF03F8 (appears twice) → Qt6Core event loop frames
  2. UTF-16 strings harvested from the spinning thread's heap/stack include the csync exclude-regex template ^(?P<exclude>%1)$|^(?P<excluderemove>%2)$|... and the path \\?\C:\Users\<user>\Nextcloud\Projects\.sync-exclude.lst — the loop is inside exclude-list handling while touching that file.
  3. Perf counters during the spin: % Processor Time ≈ 100 (one core), IO Read/Write Bytes/sec = 0, no TCP connections owned by the process.
  4. The last network job logged before the freeze is always the LSCOL of the directory containing the .sync-exclude.lst.

Ruled out (each tested): sync journal corruption (deleted .sync_.db — hang returns), stale CfAPI sync root (unregistered + folder re-added — first sync OK, hang returns), PIN state (cleared — still hangs), server side (33.0.5.1 healthy; same tree syncs fine from the Linux client), global sync-exclude.lst contents (restored to stock — still hangs), system clock (0 min drift vs independent source).

Workaround: disabling virtual files for the folder ("Disable virtual file support") fully resolves it — full sync completes, CPU normal.

Full --logdebug logs of several runs available on request.

Steps to reproduce

  1. Windows 11, client 33.0.7, add a folder sync connection WITH virtual files (wincfapi).
  2. Have the synced tree contain a subdirectory with its own .sync-exclude.lst (ours: 67 bytes, plain ASCII patterns like .venv, node_modules — created on the Linux side).
  3. Let the initial sync finish — it works, the exclude file becomes a dehydrated placeholder.
  4. Restart the client (or wait for the next sync run).
  5. Client spins at 100% of one core forever; log frozen; no network activity.

Expected behavior

The engine should either hydrate the per-directory .sync-exclude.lst on demand before reading it, or skip/warn gracefully if it cannot be read — and the sync should complete. It must not livelock waiting for a hydration that it alone can service.

Which files are affected by this bug

Any per-directory .sync-exclude.lst inside a VFS-synced tree (in our case <sync root>/Projects/.sync-exclude.lst). Client-side the loop is in nextcloud_csync.dll (exclude handling / discovery) + VFS cfapi plugin.

Operating system

Windows

Which version of the operating system you are running.

Windows 11 Pro 24H2, build 26200

Installation method

Official Windows MSI

Nextcloud Server version

33.0.5.1

Nextcloud Desktop Client version

33.0.0

Did this occur after an update or on a clean installation?

Clean desktop client installation

Are you using the Nextcloud Server Encryption module?

No

Are you using an external user-backend?

  • Default internal user-backend
  • LDAP or Active Directory
  • SSO - SAML
  • Other

Nextcloud Server logs

Additional info

Exact versions: Desktop Client 33.0.7 (build 20260629), Server 33.0.5.1 (self-hosted).

  • Dual-boot machine; the SAME server account and the SAME tree sync fine from the Linux desktop client (no VFS there) — server-side data is healthy.
  • The per-directory .sync-exclude.lst that triggers the livelock is 67 bytes of plain ASCII (patterns: .venv, pycache, *.pyc, *.egg-info, node_modules, .pio, .pytest_cache), originally created on the Linux side and synced to the server.
  • Reproduced consistently: ~10 client restarts across two days, plus full folder reset (sync-root unregister + journal wipe + re-add) — first sync always completes, every next run livelocks.
  • Workaround confirmed: disabling virtual file support for the folder → full sync completes normally, CPU idle.
  • Can provide: full --logdebug logs of several hanging runs, and thread stack samples (module+offset) taken during the spin.

Metadata

Metadata

Assignees

Type

Fields

No fields configured for Bug.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions