nextcloud / nextcloud/desktop

[Bug]: wincfapi 33.0.x sends truncated uploads on large online-only trees (works on 4.0.x)

Open
#10,310 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
3.9k
Forks
1k
Avg merge
1d 17h
Merged PRs (30d)
123

Description

### Summary
Large VFS tree, files kept online-only. On **33.0.7**, local changes never reach the server. On the **4.0.x** line the same workflow works. This is a regression on the upload path (same VFS layer as #9858).

Scope note: the differentiating change (on-demand cfapi fetch, see the root-cause comment) is present in **all 33.0.x** tags and disabled in **all 4.0.x** tags, so the affected code path is in every 33.0.x. Only **33.0.7** was tested in the field.

### Core failure: truncated PUTs
The client announces a `Content-Length` but sends fewer bytes, and the count differs on each retry of the same file. The server rejects the PUT:
```
PUT .../01-Implantation-V14...SLDASM (size 48501396)
Sabre\DAV\Exception\BadRequest: "Expected filesize: 48501396 bytes but read ...: 10387456 bytes"
# retry, same file: "...: 843776 bytes"
mirall/33.0.7 (build 20260629) wincfapi
```
In the client discovery logs, each failing file is a **regular local file** (`ItemTypeFile`, not virtual), queued `Up`, with local size = the announced Content-Length (= the server's Expected filesize exactly), while far fewer bytes are read:
```
01-Implantation-...SLDASM db/local/remote = 48167772/48501396/48167772 ItemTypeFile SYNC/Up (read 10387456)
11158 -- PLAN IMPLANTATION.SLDDRW 0/7695064/0 db=ItemTypeSkip (no DB record) NEW/Up (read 5849088)
INVERSE V3 ASSEMBLAGE ...SLDASM 1568662/1826201/1568662 ItemTypeFile SYNC/Up (read 720896)
```
So a placeholder whose content is not fully present locally is uploaded as a normal file at full logical size, and the read truncates it. Two also show `metadata missing: /true/`. Other files are correctly virtual (a `.STEP` is `ItemTypeVirtualFile` / `Down`). No size-threshold claim.

### Consequence: sync never converges
Rejected/interrupted uploads get classified as network errors, which terminate and retry the sync, so nothing lands. This is downstream, not a trigger (account-state, folderman and syncengine are unchanged vs 4.0.x):
```
AccountState: "Connected" -> "Network error" -> folder Terminating! -> Aborting sync in propagator...
```
48h capture: 963 files queued Up, 1 sync `Success`, 3 aborts, `RemoteHostClosedError` x7, `OperationCanceledError` x9.

### Expected
Reads for upload should return the full content (as on 4.0.x). A file should not be uploaded before it is fully materialised.

### Environment
Nextcloud Desktop **33.0.7** (`wincfapi`), git `497d66`, **Windows 11 (10.0.26200)**. Works on the **4.0.x** line (incl. 4.0.10). Server: Nextcloud 33.0.1.

Related: #9858

Contributor guide

Open the contributing guide

Research direction

Start with the Windows wincfapi upload path and compare the on-demand cfapi fetch behavior in the 33.0.x and 4.0.x lines, using the related issue #9858 for context. Reproduce with a large online-only VFS tree and verify that queued regular files are fully materialised before upload and that the PUT read count matches Content-Length.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.