# Nextcloud Sync Diagnosis via Cloudflare Tunnel

## 2026-06-12 Incident

### Symptoms
- Doro reported "同步不流畅，更新很难顺利同步"
- Multiple PDF files (~10MB each) failed to upload repeatedly over several hours
- Desktop client (mirall/33.0.5, Windows 10) kept retrying

### Log Evidence

**Nextcloud log** (`/var/www/html/data/nextcloud.log`):
```
level:3 | user:doro | method:PUT | BadRequest
"预期文件大小为10821497字节，实际从Nextcloud客户端读入并写入Nextcloud存储空间的大小为5758976字节。
 可能是发送端发生了网络问题，或者是服务器写入存储设备时发生错误。"
```
- Expected: ~10.8MB, actual written: 3-7MB (varies per attempt)
- Same file attempted 10+ times between 02:12-08:03 UTC (10:12-16:03 BJT)

**Cloudflared log** (`journalctl -u cloudflared-nextcloud.service`):
```
ERR error="Incoming request ended abruptly: context canceled" connIndex=2
ERR Request failed error="Incoming request ended abruptly: context canceled"
    dest=https://maggie-share.shazhou.work/remote.php/dav/files/doro/...万禹案-再审申请书附件材料.pdf
```
- Also: `failed to run the datagram handler error="timeout: no recent network activity"`
- QUIC stream acceptance failures

### Root Cause Analysis

1. **Cloudflare free-tier 100-second timeout**: Hard limit on edge nodes for single HTTP requests. Not configurable via tunnel YAML.
2. **No chunked upload**: Desktop client uploaded 10MB files as single PUT requests. At Doro's upload bandwidth, 100s wasn't enough.
3. **`connectTimeout: 120s`** in tunnel config only governs connection establishment, not transfer duration.
4. **Server-side chunking was already enabled** (`chunking: 1.0`, `bigfilechunking: true`) — the problem was purely client-side threshold.

### Failed Files
- 万禹案-再审申请书附件材料-完整版.pdf (~10.8MB, multiple renamed versions)
- 万禹案-再审申请书附件材料.pdf (~9.9MB)
- 万禹行政诉讼及撤销材料-书签版.pdf (~33MB, different error path)
- 0612_万禹案-再审申请书附件材料.pdf (~11.2MB)

### Fix Applied
Client-side: `%APPDATA%\Nextcloud\nextcloud.cfg` → `[General]` → `chunkSize=5242880` (5MB per chunk)

### Diagnostic Commands
```bash
# 1. Check server capabilities
curl -s -u USER:PASS "http://localhost:5000/ocs/v1.php/cloud/capabilities?format=json" \
  -H "OCS-APIRequest: true" | python3 -c "
import sys,json; d=json.load(sys.stdin)
caps=d['ocs']['data']['capabilities']
print('DAV:', json.dumps(caps.get('dav',{}), indent=2))
print('Files:', json.dumps(caps.get('files',{}), indent=2))"

# 2. Test chunked upload endpoint
curl -s -o /dev/null -w "%{http_code}" -X MKCOL \
  -u USER:PASS http://localhost:5000/remote.php/dav/uploads/USER/test-chunk
# Should return 201

# 3. Nextcloud error log (today's level 3+ errors)
docker exec nextcloud-nextcloud-1 bash -c \
  "cat /var/www/html/data/nextcloud.log" | grep "$(date -u +%Y-%m-%d)" | grep '"level":3'

# 4. Cloudflared errors
journalctl -u cloudflared-nextcloud.service --since today | grep -i "ERR\|error\|timeout\|cancel"

# 5. Tunnel config
cat /home/maggie/.cloudflared/maggie-share.yml
```

### Infrastructure Context
- Tunnel config: `/home/maggie/.cloudflared/maggie-share.yml`
- Service: `cloudflared-nextcloud.service` (systemd)
- Tunnel ID: 1af48f57-9e20-41d6-a09c-0ef9547eeb88
- Hostnames: maggie-share.shazhou.work (Nextcloud), office.shazhou.work (OnlyOffice)
- PHP limits: upload_max=512M, post_max=512M, memory=512M — not the bottleneck
- Disk: 8% used (412GB free) — not the bottleneck
