nextcloud / nextcloud/desktop

[Bug]: Windows WinCfAPI hydration hangs for online-only files <= 4096 bytes

Open
#10,845 0 comments 0 reactions 0 assignees View on GitHub
0. Needs triage bug
Dominant language
C++
Stars
3.9k
Forks
1k
Avg merge
1d 21h
Merged PRs (30d)
127

Description

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

- [x] This is a **bug**, not a question or a configuration issue.
- [x] This issue is **not** already reported on Github (I have searched for it).
- [x] Nextcloud Server and Desktop Client are **up to date**. See [Server Maintenance and Release Schedule](https://github.com/nextcloud/server/wiki/Maintenance-and-Release-Schedule) and [Desktop Releases](https://nextcloud.com/install/#install-clients) for supported versions.
- [x] I agree to follow Nextcloud's [Code of Conduct](https://nextcloud.com/contribute/code-of-conduct/)

### Bug description

On Windows 10 with Virtual Files (WinCfAPI), opening some small online-only files hangs instead of hydrating them.

The issue was originally observed with normal .rdp files around 2.4-2.5 kB. I then reproduced it with synthetic files of exact sizes and found a deterministic boundary:

| File size | Result |
|---|---|
| 4095 bytes | FAIL - read/hydration hangs |
| 4096 bytes | FAIL - read/hydration hangs |
| 4097 bytes | OK - hydrates in ~0.4 s |
| 8192 bytes | OK - hydrates in <1 s |

For the failing files, the Nextcloud client downloads the complete file successfully and logs:

`GETFileJob finished`

followed by:

`Hydration job finished ... OCC::HydrationJob::Success`

However, the Windows CfAPI placeholder remains `Offline` / `RecallOnDataAccess` and the process trying to read the file remains blocked.

About 60 seconds later the client logs:

`Cancel fetch data`

The problem is not specific to Explorer or Total Commander. It was reproduced with a minimal PowerShell/.NET test that opens the file and reads a single byte.

A 4097-byte file created and tested in exactly the same way hydrates successfully.

### Steps to reproduce

1. Configure a sync folder on Windows using Nextcloud Virtual Files (WinCfAPI).

2. Create three files with exact sizes:
- 4095 bytes
- 4096 bytes
- 4097 bytes

3. Let all three files finish syncing to the server.

4. Use "Free up local space" / make them online-only.

5. Verify that each test file is an online-only CfAPI placeholder.

6. Open each file, or perform a minimal read of one byte.

7. Observe:
- 4095 bytes: the read blocks and hydration does not complete.
- 4096 bytes: the read blocks and hydration does not complete.
- 4097 bytes: hydration completes normally.

For the 4096-byte failing case, the HTTP download itself completes in about 80 ms and the client reports `HydrationJob::Success`, but the Windows placeholder remains offline and the caller stays blocked.

Approximately 60 seconds later the client logs `Cancel fetch data`.

### Expected behavior

Online-only files should hydrate successfully regardless of their size.

Files of 4095 and 4096 bytes should behave like the 4097-byte file: the data should be transferred to Windows CfAPI, the placeholder should become hydrated, and the application reading the file should return normally.

### Which files are affected by this bug

Online-only files in a Windows WinCfAPI virtual-files sync. The issue appears to be size-dependent rather than extension-dependent. It was originally observed with .rdp files around 2.4-2.5 kB and reproduced with synthetic .bin files.

### Operating system

Windows

### Which version of the operating system you are running.

Windows 10 Pro 22H2, build 19045

### Installation method

Official Windows MSI

### Nextcloud Server version

33.0.9

### Nextcloud Desktop Client version

34.0.3

### 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?

- [x] Default internal user-backend
- [ ] LDAP or Active Directory
- [ ] SSO - SAML
- [ ] Other

### Nextcloud Server logs

```shell

```

### Additional info

The exact 4096/4097-byte boundary may be relevant to the WinCfAPI implementation.

The current CfAPI wrapper uses a 4096-byte transfer block:

`constexpr auto cfapiBlockSize = 4096;`

I am not claiming this is necessarily the root cause, but the experimentally observed boundary is exactly between 4096 bytes (fails) and 4097 bytes (works).

For the failing 4096-byte case, the sequence is:

1. CfAPI fetch request received
2. GET starts
3. GET completes successfully (~80 ms)
4. `Hydration job finished ... OCC::HydrationJob::Success`
5. sync journal is updated to `CSyncEnums::ItemTypeFile`
6. Windows placeholder nevertheless remains `Offline` / `RecallOnDataAccess`
7. the requesting process remains blocked
8. roughly 60 seconds later: `Cancel fetch data`

Possibly related:
- #7747 - Windows VFS hydration/open failures
- #4509 - historical size-dependent VFS problem with small files (dehydration rather than hydration)

No relevant server-side error was observed during reproduction. The file GET completes successfully; the failure occurs afterwards in the Windows WinCfAPI hydration path.

Contributor guide

Open the contributing guide

Research direction

Start by locating the WinCfAPI wrapper and the `cfapiBlockSize = 4096` definition, then trace the hydration path after `HydrationJob::Success`. Reproduce the issue with 4095-, 4096-, and 4097-byte online-only files using the described minimal read. Done means the 4095- and 4096-byte placeholders hydrate and the reading process returns normally, without the delayed cancellation.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.