# Nextcloud File Upload Diagnostics When files appear visible in the Nextcloud web UI but `find` on the container filesystem returns nothing, use this diagnostic sequence. ## Step 1: Check physical filesystem ```bash docker exec find '/' -type f -exec ls -la {} \; ``` Look for `.part` and `.ocTransferId*` files — these are incomplete upload fragments. ## Step 2: Rescan ```bash docker exec -u www-data php occ files:scan admin --path='' ``` ## Step 3: Check Nextcloud logs ```bash docker exec tail -20 /var/www/html/data/nextcloud.log | python3 -c " import sys, json for line in sys.stdin: try: d = json.loads(line.strip()) if d.get('level', 0) >= 2: print(f'[{d.get(\"time\",\"?\")}] {d.get(\"message\",\"\")[:300]}') except: pass " ``` Upload failures show: "预期文件大小为 X字节,实际...写入...Y字节" ## Step 4: Query MariaDB directly Find the DB password first: ```bash docker exec grep dbpassword /var/www/html/config/config.php ``` Then query (use `mariadb` client, not `mysql`): ```bash docker exec nextcloud-db-1 mariadb -u nextcloud -p nextcloud -e " SELECT f.fileid, f.path, f.name, f.size, FROM_UNIXTIME(f.mtime) as modified FROM oc_filecache f WHERE f.path LIKE '%%' ORDER BY f.path; " ``` To find children of a directory (by parent fileid): ```bash ... -e "SELECT f.fileid, f.parent, f.path, f.name, f.size FROM oc_filecache f WHERE f.parent IN (, );" ``` ## Step 5: Clean up fragments ```bash docker exec find '' -name '*.part' -delete docker exec find '' -name '*.ocTransferId*' -delete ``` ## Common root cause Cloudflare Tunnel (free tier) truncates large file uploads. The Nextcloud chunked upload protocol partially writes, then the connection drops. Repeated retries produce the same result. **Solution**: Receive files via alternate channel (WeChat private message → `~/.hermes/cache/documents/`) and `docker cp` into Nextcloud. ## Quirk: docker cp'd file present + md5 correct, but `files:scan` returns 0 and DB row missing (2026-06-17) After `docker cp` + `chown www-data` a new xlsx, `php occ files:scan admin --path='小Maggie协作区/.../世茂'` returned all-zeros (`Folders 0 Files 0`) and `oc_filecache` had **no row** for the file — so it was invisible in the web UI despite physically existing with a correct md5. **Root cause**: `files:scan` keys off directory mtime; a fresh `docker cp` into an existing dir doesn't always bump the parent mtime, so the scanner skips it. **Fix** (verified): ```bash # 1. touch the parent dir to force an mtime change docker exec bash -c "touch '/var/www/html/data/admin/files/'" # 2. rescan using the admin/files/ prefixed --path form (not the bare share path) docker exec -u www-data php occ files:scan --path="admin/files/" ``` This returns `Updated N` and registers the file. **Always verify after upload** by querying `oc_filecache` for the filename (Step 4) — md5 match alone does NOT prove the file is indexed/visible. Don't tell the user "uploaded" until the DB row exists.