Repository navigation
[Bug]: Chunking v2 upload session expires after a fixed 24h TTL (never refreshed), breaking large uploads on slow connections with 412 "Missing metadata for chunked upload" #61604
Description
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration/webserver/proxy issue.
- This issue is not already reported on Github OR Nextcloud Community Forum (I've searched it).
- Nextcloud Server is up to date. See Maintenance and Release Schedule for supported versions.
- I agree to follow Nextcloud's Code of Conduct.
Bug description
With chunking v2 (the bulk/web uploader, OCA\DAV\Upload\ChunkingV2Plugin), the per-session metadata — the multipart uploadId, target path and target id — is stored in the distributed cache with a hard-coded 24h TTL (86400), set once in afterMkcol() and never refreshed by subsequent chunk PUTs (beforePut() only reads it via prepareUpload()).
As a result, any chunked upload whose total wall-clock duration exceeds 24h fails, even though the distributed cache (Redis) is correctly configured and healthy. ~24h after the MKCOL, the cache entry simply ages out; the next chunk PUT finds no metadata and checkPrerequisites() throws:
412 Precondition Failed
Missing metadata for chunked upload. The distributed cache does not hold the information of previous requests.
The web uploader then 400s the remaining queued chunks and DELETEs the whole session, discarding ~24h of successfully-uploaded data. No MOVE/finalization ever happens.
This is distinct from #38801: there the distributed cache is absent/misconfigured (the checkPrerequisites() "no proper distributed cache" BadRequest path). Here the cache is present and working — the entry expires purely on age.
Impact: large files become effectively un-uploadable for users on slow uplinks. Real case: a ~10–12 GB file over an ADSL upstream (~120 KB/s effective). ~1000 chunks (10 MiB each) upload fine over ~24h, then the very next chunk gets 412 right at the 24h mark. The user can never beat the clock because the upload physically takes longer than the session lifetime.
Offending code (apps/dav/lib/Upload/ChunkingV2Plugin.php, same on master; line numbers from v32.0.11):
afterMkcol()—$this->cache->set($this->uploadFolder->getName(), [...], 86400);(L133–137) — set once at session creation.beforePut()— uploads the part but never re-sets the cache entry → no sliding expiration.prepareUpload()— onlygets the metadata.checkPrerequisites()— throwsPreconditionFailed('Missing metadata for chunked upload…')whenuploadId/uploadPathare null (L290).
Steps to reproduce
- Configure S3 primary object storage (any
IChunkedFileWrite/IObjectStoreMultiPartUploadbackend) and a Redis distributed cache (memcache.distributed). - Throttle the client uplink so a single large file takes > 24h to upload (e.g. ~12 GB at ~120 KB/s). To repro fast, temporarily lower the
86400TTL to a few minutes inafterMkcol(). - Upload the large file through the web uploader (
MKCOL /remote.php/dav/uploads/<user>/web-file-upload-<id>, thenPUT …/<n>chunks). - ~24h after the
MKCOL(or after the shortened TTL), observe the next chunkPUTreturn412"Missing metadata for chunked upload", the following chunks return400, and the client issues aDELETEon the session. The upload is lost.
Observed server-side log sequence (real incident, single nginx replica):
25/Jun 04:48:39 MKCOL …/web-file-upload-XXXX 201 ← session created
26/Jun 04:46:49 PUT …/web-file-upload-XXXX/1000 200 ← last good chunk (~24h in)
26/Jun 04:53:18 PUT …/web-file-upload-XXXX/1001 412 ← metadata expired
26/Jun 04:53:26 PUT …/web-file-upload-XXXX/1002..1005 400
26/Jun 04:53:27 DELETE …/web-file-upload-XXXX 204 ← client aborts, data lost
Expected behavior
An actively-progressing upload must not be garbage-collected on wall-clock age alone. Either:
- Refresh the TTL (sliding expiration) on every successful chunk
PUTinbeforePut(), so the session only expires after 24h of inactivity; and/or - make the TTL admin-configurable (system config) instead of a hard-coded
86400.
Nextcloud Server version
32
Operating system
Debian/Ubuntu
PHP engine version
PHP 8.3
Web server
Nginx
Database engine version
PostgreSQL
Is this bug present after an update or on a fresh install?
Fresh Nextcloud Server install
Are you using the Nextcloud Server Encryption module?
Encryption is Disabled
What user-backends are you using?
- Default user-backend (database)
- LDAP/ Active Directory
- SSO - SAML
- Other
Configuration report
{
"system": {
"memcache.local": "\\OC\\Memcache\\APCu",
"apps_paths": [
{ "path": "/var/www/html/apps", "url": "/apps", "writable": false },
{ "path": "/var/www/html/custom_apps", "url": "/custom_apps", "writable": true }
],
"integrity.check.disabled": true,
"filelocking.enabled": true,
"log_type": "syslog",
"loglevel": 1,
"default_phone_region": "FR",
"memcache.distributed": "\\OC\\Memcache\\Redis",
"memcache.locking": "\\OC\\Memcache\\Redis",
"overwriteprotocol": "https",
"trusted_proxies": "***REMOVED SENSITIVE VALUE***",
"objectstore": {
"class": "\\OC\\Files\\ObjectStore\\S3",
"arguments": {
"bucket": "001",
"region": "region",
"hostname": "mystorage.com",
"port": "443",
"storageClass": "",
"objectPrefix": "urn:oid:",
"autocreate": true,
"use_ssl": true,
"use_path_style": true,
"legacy_auth": false,
"key": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"sse_c_key": "***REMOVED SENSITIVE VALUE***"
}
},
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": ["mydomain"],
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"dbtype": "pgsql",
"version": "32.0.11.1",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbtableprefix": "oc_",
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"instanceid": "***REMOVED SENSITIVE VALUE***",
"maintenance": false,
"appstoreenabled": false,
"redis.cluster": {
"seeds": "***REMOVED SENSITIVE VALUE***",
"password": "***REMOVED SENSITIVE VALUE***"
},
"overwritehost": "mydomain",
"files.chunked_upload.max_size": 10485760
}
}List of activated Apps
Enabled:
- activity: 5.0.0
- admin_audit: 1.22.0
- bruteforcesettings: 5.0.0
- calendar: 6.5.0
- circles: 32.0.0
- cloud_federation_api: 1.16.0
- comments: 1.22.0
- contacts: 8.3.13
- contactsinteraction: 1.13.1
- dashboard: 7.12.0
- dav: 1.34.2
- federatedfilesharing: 1.22.0
- federation: 1.22.0
- files: 2.4.0
- files_downloadlimit: 5.0.0
- files_reminders: 1.5.0
- files_sharing: 1.24.1
- files_trashbin: 1.22.0
- files_versions: 1.25.0
- lookup_server_connector: 1.20.0
- notifications: 5.0.0
- oauth2: 1.20.0
- oidc_login: 3.3.1+murena.20260513
- onlyoffice: 9.14.0
- password_policy: 4.0.0
- photos: 5.0.0
- privacy: 4.0.0
- profile: 1.1.0
- provisioning_api: 1.22.0
- serverinfo: 4.0.0
- settings: 1.15.1
- sharebymail: 1.22.0
- spreed: 22.0.13
- systemtags: 1.22.0
- text: 6.0.2
- theming: 2.7.0
- twofactor_backupcodes: 1.21.0
- updatenotification: 1.22.0
- user_status: 1.12.0
- viewer: 5.0.0
- webhook_listeners: 1.3.0
- workflowengine: 2.14.0
Disabled:
- encryption: 2.20.0
- files_external: 1.24.1
- user_ldap: 1.23.0Nextcloud Signing status
Nextcloud Logs
[25/Jun/2026:04:48:39] "MKCOL /remote.php/dav/uploads/<user>/web-file-upload-XXXX" 201 ← session created
[26/Jun/2026:04:46:49] "PUT /remote.php/dav/uploads/<user>/web-file-upload-XXXX/1000" 200 ← last good chunk (~24h in)
[26/Jun/2026:04:53:18] "PUT /remote.php/dav/uploads/<user>/web-file-upload-XXXX/1001" 412 ← metadata expired (the bug)
[26/Jun/2026:04:53:26] "PUT /remote.php/dav/uploads/<user>/web-file-upload-XXXX/1002" 400
[26/Jun/2026:04:53:26] "PUT /remote.php/dav/uploads/<user>/web-file-upload-XXXX/1003" 400
[26/Jun/2026:04:53:26] "PUT /remote.php/dav/uploads/<user>/web-file-upload-XXXX/1004" 400
[26/Jun/2026:04:53:26] "PUT /remote.php/dav/uploads/<user>/web-file-upload-XXXX/1005" 400
[26/Jun/2026:04:53:27] "DELETE /remote.php/dav/uploads/<user>/web-file-upload-XXXX" 204 ← web uploader aborts, ~24h of data lostAdditional info
- The
partId 1..10000guard (beforePut()) is not the limiter here — failure occurs at part ~1001, well within range; quota is also not involved (plenty of free space). - Workarounds available to admins/users today: upload from a faster link so the transfer completes in < 24h, or split the file into parts each uploadable in < 24h. There is no config knob to extend the session lifetime.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
[-]Bug]: Chunking v2 upload session expires after a fixed 24h TTL (never refreshed), breaking large uploads on slow connections with 412 "Missing metadata for chunked upload"[/-][+][Bug]: Chunking v2 upload session expires after a fixed 24h TTL (never refreshed), breaking large uploads on slow connections with 412 "Missing metadata for chunked upload"[/+]solracsf commentedon Jun 29, 2026
Working on this.