Yes, I think this would explain it - the chunks are not constant size but vary depending on the upload speed. When I upload large files via web UI they work perfectly fine and I can see all the chunks are fixed at 10 MB.
What I found about my server is that it has a fixed maximum upload size in its nginx config, which appears to be around 64 MB. Possibly, if a chunk is bigger for whatever reason the upload fails. I don’t think I can change that server limit.
But here is a log from a failed upload, from the beginning to the first error:
08-12 11:27:17:356 [ info sync.networkjob.put ]: PUT of "https://owncloud.example.com/remote.php/dav/uploads/admin/2292627051/00000000" FINISHED WITH STATUS "OK" QVariant(int, 201) QVariant(QString, "Created")
08-12 11:27:17:383 [ info sync.propagator.upload ]: Chunked upload of 10000000 bytes took 5104 ms, desired is 60000 ms, expected good chunk size is 117554858 bytes and nudged next chunk size to 63777429 bytes
08-12 11:27:17:459 [ info sync.accessmanager ]: 3 "" "https://owncloud.example.com/remote.php/dav/uploads/admin/2292627051/00000001" has X-Request-ID "79254ac7-7158-4508-b345-eb9f9291886c"
08-12 11:27:17:460 [ info sync.networkjob ]: OCC::PUTFileJob created for "https://owncloud.example.com" + "" "OCC::PropagateUploadFileNG"
08-12 11:27:18:658 [ debug gui.account.state ] [ OCC::AccountState::checkConnectivity ]: "admin@owncloud.example.com" The last ETag check succeeded within the last 30 secs. No connection check needed!
08-12 11:27:18:799 [ info sync.accessmanager ]: 6 "PROPFIND" "https://owncloud.example.com/remote.php/dav/files/admin/" has X-Request-ID "769515ba-9a43-4e2d-8104-3b4063716e21"
08-12 11:27:18:799 [ debug sync.cookiejar ] [ OCC::CookieJar::cookiesForUrl ]: QUrl("https://owncloud.example.com/remote.php/dav/files/admin/") requests: (QNetworkCookie("oc_sessionPassphrase=nnDDyhzmHnPW8KBmK0Id4SjD68snAzqSjeTNhsfo9EjWsAXGt4ehZiYbX9MQNxo6LGBRkokXLu6gtoVo8ShPZvJk%2F1WbdUhfjqxh1c7m8XqdEp5Q%2BqUrMlkRuMvwiOAT; secure; HttpOnly; domain=owncloud.example.com; path=/"), QNetworkCookie("ocrdki0ek0ba=c8d65708dd058e3831f734c4bc4a755c; secure; HttpOnly; domain=owncloud.example.com; path=/"))
08-12 11:27:18:800 [ info sync.networkjob ]: OCC::PropfindJob created for "https://owncloud.example.com" + "/" "OCC::QuotaInfo"
08-12 11:27:19:069 [ info sync.networkjob.propfind ]: PROPFIND of QUrl("https://owncloud.example.com/remote.php/dav/files/admin/") FINISHED WITH STATUS "OK"
08-12 11:27:19:070 [ debug sync.networkjob ] [ OCC::AbstractNetworkJob::slotFinished ]: Network job OCC::PropfindJob finished for "/"
08-12 11:27:46:636 [ warning sync.networkjob ]: QNetworkReply::NetworkError(UnknownNetworkError) "Unable to write" QVariant(Invalid)
08-12 11:27:46:637 [ info sync.networkjob.put ]: PUT of "https://owncloud.example.com/remote.php/dav/uploads/admin/2292627051/00000001" FINISHED WITH STATUS "UnknownNetworkError Unable to write" QVariant(Invalid) QVariant(Invalid)
08-12 11:27:46:638 [ debug sync.propagator.upload ] [ OCC::PropagateUploadFileCommon::commonErrorHandling ]: ""
08-12 11:27:46:639 [ debug sync.database.sql ] [ OCC::SqlQuery::bindValue ]: SQL bind 1 QVariant(QString, "large/mysql-installer-community-8.0.13.0.msi")
08-12 11:27:46:640 [ debug sync.database.sql ] [ OCC::SqlQuery::exec ]: SQL exec "SELECT lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget, errorCategory, requestId FROM blacklist WHERE path=?1 COLLATE NOCASE"
08-12 11:27:46:641 [ warning sync.propagator ]: Could not complete propagation of "large/mysql-installer-community-8.0.13.0.msi" by OCC::PropagateUploadFileNG(0x7bed3e8) with status 1 and error: "Unable to write"
08-12 11:27:46:650 [ debug sync.statustracker ] [ OCC::SyncFileStatusTracker::slotItemCompleted ]: Item completed "large/mysql-installer-community-8.0.13.0.msi" 1 8
08-12 11:27:46:651 [ debug sync.database.sql ] [ OCC::SqlQuery::bindValue ]: SQL bind 1 QVariant(qlonglong, 1999444939382454132)
08-12 11:27:46:652 [ debug sync.database.sql ] [ OCC::SqlQuery::exec ]: SQL exec "SELECT path, inode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentchecksumtype.name || ':' || contentChecksum FROM metadata LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id WHERE phash=?1"
08-12 11:27:46:653 [ debug sync.database.sql ] [ OCC::SqlQuery::bindValue ]: SQL bind 1 QVariant(qlonglong, 1999444939382454132)
08-12 11:27:46:654 [ debug sync.database.sql ] [ OCC::SqlQuery::exec ]: SQL exec "SELECT path, inode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentchecksumtype.name || ':' || contentChecksum FROM metadata LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id WHERE phash=?1"
08-12 11:27:46:656 [ debug sync.localdiscoverytracker ] [ OCC::LocalDiscoveryTracker::slotItemCompleted ]: inserted error item "large/mysql-installer-community-8.0.13.0.msi"
08-12 11:27:46:656 [ debug sync.networkjob ] [ OCC::AbstractNetworkJob::slotFinished ]: Network job OCC::PUTFileJob finished for ""
08-12 11:27:46:664 [ debug sync.database.sql ] [ OCC::SqlQuery::exec ]: SQL exec "SELECT phash, path FROM metadata order by path"
08-12 11:27:46:664 [ debug sync.database.sql ] [ OCC::SqlQuery::exec ]: SQL exec "PRAGMA wal_checkpoint(FULL);"
08-12 11:27:46:664 [ debug sync.database ] [ OCC::SyncJournalDb::walCheckpoint ]: took 0 msec
08-12 11:27:46:665 [ debug sync.database.sql ] [ OCC::SqlQuery::exec ]: SQL exec "SELECT path FROM conflicts"
08-12 11:27:46:665 [ debug sync.database ] [ OCC::SyncJournalDb::commitInternal ]: Transaction commit "All Finished."
08-12 11:27:46:667 [ info sync.database ]: Closing DB "D:/ownCloud/._sync_3f1bf5db7a93.db"
08-12 11:27:46:668 [ debug sync.database ] [ OCC::SyncJournalDb::commitTransaction ]: No database Transaction to commit
08-12 11:27:46:707 [ info sync.engine ]: CSync run took 37078 ms
08-12 11:27:46:708 [ debug sync.localdiscoverytracker ] [ OCC::LocalDiscoveryTracker::slotSyncFinished ]: sync failed, keeping last sync's local discovery path list
08-12 11:27:46:764 [ debug gui.folderwatcher ] [ OCC::FolderWatcher::pathIsIgnored ]: * Ignoring file "D:/ownCloud/._sync_3f1bf5db7a93.db-wal"
08-12 11:27:46:765 [ debug gui.folderwatcher ] [ OCC::FolderWatcher::pathIsIgnored ]: * Ignoring file "D:/ownCloud/._sync_3f1bf5db7a93.db"
08-12 11:27:46:765 [ debug gui.folderwatcher ] [ OCC::FolderWatcher::pathIsIgnored ]: * Ignoring file "D:/ownCloud/._sync_3f1bf5db7a93.db-shm"
08-12 11:27:46:766 [ debug gui.folderwatcher ] [ OCC::FolderWatcher::pathIsIgnored ]: * Ignoring file "D:/ownCloud/._sync_3f1bf5db7a93.db-wal"
08-12 11:27:46:766 [ info gui.folder ]: Client version 2.5.4 (build 11415) Qt 5.11.2 SSL OpenSSL 1.1.1 11 Sep 2018
08-12 11:27:46:766 [ warning gui.folder ]: SyncEngine finished with ERROR
08-12 11:27:46:778 [ info gui.folder ]: Folder sync result: 1
08-12 11:27:46:779 [ info gui.folder ]: the last 1 syncs failed
08-12 11:27:46:789 [ info gui.application ]: Sync state changed for folder "https://owncloud.example.com/remote.php/dav/files/admin/" : "Error"
08-12 11:27:46:794 [ debug gui.folderwatcher ] [ OCC::FolderWatcher::pathIsIgnored ]: * Ignoring file "D:/ownCloud/.owncloudsync.log"
08-12 11:27:46:990 [ info gui.folder.manager ]: <========== Sync finished for folder [D:\ownCloud] of account [admin@owncloud.example.com] with remote [https://owncloud.example.com/remote.php/dav/files/admin/]
08-12 11:27:46:991 [ info gui.folder.manager ]: Starting the next scheduled sync in 9 seconds
08-12 11:27:49:071 [ info sync.accessmanager ]: 6 "PROPFIND" "https://owncloud.example.com/remote.php/dav/files/admin/" has X-Request-ID "6ad2ed94-feca-4d38-9ccb-51b7ce0c8b26"
08-12 11:27:49:072 [ debug sync.cookiejar ] [ OCC::CookieJar::cookiesForUrl ]: QUrl("https://owncloud.example.com/remote.php/dav/files/admin/") requests: (QNetworkCookie("oc_sessionPassphrase=nnDDyhzmHnPW8KBmK0Id4SjD68snAzqSjeTNhsfo9EjWsAXGt4ehZiYbX9MQNxo6LGBRkokXLu6gtoVo8ShPZvJk%2F1WbdUhfjqxh1c7m8XqdEp5Q%2BqUrMlkRuMvwiOAT; secure; HttpOnly; domain=owncloud.example.com; path=/"), QNetworkCookie("ocrdki0ek0ba=c8d65708dd058e3831f734c4bc4a755c; secure; HttpOnly; domain=owncloud.example.com; path=/"))
08-12 11:27:49:074 [ info sync.networkjob ]: OCC::PropfindJob created for "https://owncloud.example.com" + "/" "OCC::QuotaInfo"
08-12 11:27:49:391 [ info sync.networkjob.propfind ]: PROPFIND of QUrl("https://owncloud.example.com/remote.php/dav/files/admin/") FINISHED WITH STATUS "OK"
08-12 11:27:49:392 [ debug sync.networkjob ] [ OCC::AbstractNetworkJob::slotFinished ]: Network job OCC::PropfindJob finished for "/"
08-12 11:27:50:657 [ debug gui.account.state ] [ OCC::AccountState::checkConnectivity ]: "admin@owncloud.example.com" The last ETag check succeeded within the last 30 secs. No connection check needed!
Yes, I know this host is not ideal for a good setup since it appears to have an upload size limit at 64 MB. But if a browser can upload large files via UI without any issues then I suppose the desktop client could do it, too? If the chunks sent by the client did not exceed the configured size (like 10 MB) then all would work fine. Isn’t there a way to limit the chunk size sent from the client?