⚠️ This issue respects the following points: ⚠️
Bug description
While investigating an Android Auto Upload problem, I noticed a server-side
behaviour that I was able to reproduce independently of the Android client.
If two PUT requests for the same chunk of the same chunked-upload collection
overlap, and one request finishes before the upload is finalized with MOVE,
the still-running PUT later returns HTTP 500.
The MOVE itself succeeds and the resulting file is complete and correct.
I reproduced this twice:
- once with a 1 MiB payload
- once with a 32 MiB random payload and a deliberately throttled PUT
In the 32 MiB test, the first PUT was confirmed to still be running when the
MOVE was performed.
I am not sure whether HTTP 500 is considered the expected response for this
race condition, so I reduced it to a client-independent curl reproducer.
Steps to reproduce
-
Create a chunked upload collection:
MKCOL /remote.php/dav/uploads/{user}/{upload-id}
Result: HTTP 201
-
Start a PUT to chunk 000001 and deliberately throttle the request so that
it remains active.
-
While the first PUT is still active, start a second PUT of the same chunk:
PUT /remote.php/dav/uploads/{user}/{upload-id}/000001
Result: HTTP 201
-
Confirm that the first PUT is still running.
-
Finalize the upload:
MOVE /remote.php/dav/uploads/{user}/{upload-id}/.file
with:
Destination: /remote.php/dav/files/{user}/{target-file}
OC-Total-Length: {payload-size}
Result: HTTP 201
-
Wait for the first, still-running PUT to finish.
Result: HTTP 500
-
Download the final file.
Result: HTTP 200. File size and SHA-256 match the original payload.
Expected behavior
I am not sure which WebDAV status code is preferred when an upload collection
has already been successfully finalized while another PUT to that collection
is still in progress.
However, returning HTTP 500 and logging "source directory is not writable"
seems misleading in this situation because the storage is writable, the MOVE
completed successfully, and the final file exists with the correct content.
Ideally this race should be handled without reporting an internal server
error.
Nextcloud Server version
35
Operating system
Other
PHP engine version
PHP 8.4
Web server
Nginx
Database engine version
PostgreSQL
Is this bug present after an update or on a fresh install?
Upgraded to a MAJOR version (ex. 31 to 32)
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
{
"system": {
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"filesystem_check_changes": 0,
"instanceid": "***REMOVED SENSITIVE VALUE***",
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": {
"1": "cloud.example.com",
"2": "example.com",
"3": "127.0.0.1",
"4": "localhost",
"7": "<internal-ip>",
"8": "nextcloud",
"9": "<internal-container-ip>",
"10": "<internal-container-ip>"
},
"tempdirectory": "/temp",
"skeletondirectory": "/config/custom_skeleton",
"supportedDatabases": [
"pgsql"
],
"dboptions": {
"2": 30,
"3": 2
},
"overwrite.cli.url": "https://cloud.example.com",
"overwritehost": "cloud.example.com",
"overwriteprotocol": "https",
"overwritecondaddr": "^<internal-container-subnet>$",
"has_internet_connection": true,
"dbtype": "pgsql",
"version": "35.0.0.10",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbport": "",
"dbtableprefix": "oc_",
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"default_phone_region": "<redacted>",
"default_language": "<redacted>",
"default_locale": "<redacted>",
"maintenance": false,
"filelocking.enabled": true,
"filelocking.debug": false,
"filelocking.ttl": 43200,
"apps_paths": [
{
"path": "/app/www/public/apps",
"url": "/apps",
"writable": false
},
{
"path": "/config/www/nextcloud/apps",
"url": "/custom_apps",
"writable": true
}
],
"mail_from_address": "***REMOVED SENSITIVE VALUE***",
"mail_smtpmode": "smtp",
"mail_sendmailmode": "smtp",
"mail_domain": "***REMOVED SENSITIVE VALUE***",
"mail_smtphost": "***REMOVED SENSITIVE VALUE***",
"mail_smtpport": "587",
"mail_smtpauth": true,
"mail_smtpname": "***REMOVED SENSITIVE VALUE***",
"mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
"mail_smtpauthtype": "LOGIN",
"mail_smtptimeout": 30,
"mail_smtp_address_family": "ipv4",
"ffmpeg": "/usr/bin/ffmpeg",
"enable_previews": true,
"preview_format": "webp",
"updater.release.channel": "stable",
"loglevel": 2,
"log_query_overhead": false,
"updater.secret": "***REMOVED SENSITIVE VALUE***",
"upgrade.disable-web": true,
"maintenance_window_start": 1,
"defaultapp": "files",
"forbidden_filename_characters": [
"\\",
"/"
],
"preview_max_memory": 1024,
"preview_max_x": 2048,
"preview_max_y": 2048,
"preview_max_scale_factor": 1,
"preview_render_max_scale": 1,
"preview_max_filesize_image": 50,
"preview_quality": 85,
"preview_standard_res": "64 256 512 1024 2048",
"data-fingerprint": "<redacted>",
"asset-pipeline.enabled": false,
"memlimit": "4G",
"htaccess.RewriteBase": "/",
"x_permitted_cross_domain_policies": "none",
"appstoreenabled": true,
"versions_retention_obligation": "auto, 3",
"shareapi_allow_share_dialog_user_enumeration": false,
"preview_ffmpeg_path": "/usr/bin/ffmpeg",
"lorelejay.preview_on_demand": false,
"logfilemode": 436,
"Dav": {
"timeout": 7200
},
"logtimezone": "<redacted>",
"log_type": "file",
"logfile": "/data/nextcloud.log",
"allow_local_remote_servers": false,
"proxy_proxies": 0,
"logformat": "",
"log_rotate_size": 104857600,
"memories.db.triggers.fcu": true,
"memories.exiftool": "/app/www/public/apps/memories/bin-ext/exiftool-amd64-musl",
"show_hidden": true,
"airlock.ignore_nomedia": true,
"logperm": 436,
"preview_max_filesize_executable": 50,
"preview_max_scale": 1,
"preview_jpeg_resample": true,
"image_magick_resample": true,
"opcache_optimization_level": 2147467263,
"enabledPreviewProviders": [
"OC\\Preview\\WebP",
"OC\\Preview\\HEIC",
"OC\\Preview\\JPEG",
"OC\\Preview\\PNG",
"OC\\Preview\\GIF",
"OC\\Preview\\BMP",
"OC\\Preview\\XBitmap",
"OC\\Preview\\Movie",
"OC\\Preview\\PDF",
"OC\\Preview\\MP3",
"OC\\Preview\\TXT",
"OC\\Preview\\MarkDown",
"OC\\Preview\\Krita",
"OC\\Preview\\SVG",
"OC\\Preview\\Image",
"OC\\Preview\\TIFF",
"OC\\Preview\\Font",
"OC\\Preview\\OpenDocument",
"OC\\Preview\\Imagick"
],
"preview_generation_max_instruction_count": 2000000,
"serverid": "<redacted>",
"mail_smtpstreamoptions": {
"ssl": {
"allow_self_signed": false,
"verify_peer": true,
"verify_peer_name": true
}
},
"memcache.local": "\\OC\\Memcache\\APCu",
"memcache.distributed": "\\OC\\Memcache\\Redis",
"memcache.locking": "\\OC\\Memcache\\Redis",
"redis": {
"host": "***REMOVED SENSITIVE VALUE***",
"port": 6379,
"password": "***REMOVED SENSITIVE VALUE***",
"timeout": 0
},
"memories.vod.disable": false,
"memories.vod.external": true,
"memories.vod.ffmpeg": "/usr/bin/ffmpeg",
"memories.vod.ffprobe": "/usr/bin/ffprobe",
"memories.vod.bind": "",
"memories.vod.connect": "<internal-service>:47788",
"memories.vod.nvenc": true,
"memories.vod.path": "/config/www/nextcloud/apps/memories/bin-ext/go-vod-amd64",
"memories.index.path.blacklist": "\\.thumbnails|@Recycle|eaDir",
"preview_exclude_folders": [
".thumbnails",
"Thumbnails",
"Recycle-Bin",
"recyclebin",
"@eaDir"
],
"preview_concurrency_all": 4,
"preview_concurrency_new": 2,
"memories.vod.use_gop_size": true,
"referrer_policy": "no-referrer-when-downgrade",
"check_data_directory_permissions": false,
"trusted_proxies": "***REMOVED SENSITIVE VALUE***",
"files.chunked_upload.max_parallel_count": 1,
"files.chunked_upload.max_size": 104857600
}
}
List of activated Apps
Enabled:
- activity: 8.0.0
- app_api: 35.0.0
- appstore: 2.0.0-dev.0
- bruteforcesettings: 8.0.0
- cloud_federation_api: 2.0.0-dev.0
- comments: 2.0.0-dev.0
- contactsinteraction: 2.0.0-dev.0
- dav: 2.0.0-dev.1
- drop_account: 3.1.0
- federatedfilesharing: 2.0.0-dev.1
- federation: 2.0.0-dev.0
- files: 3.0.0-dev.0
- files_accesscontrol: 6.0.0
- files_downloadlimit: 5.3.0
- files_lock: 35.0.0
- files_pdfviewer: 8.0.0
- files_sharing: 2.0.0-dev.1
- files_trashbin: 2.0.0-dev.0
- files_versions: 2.0.0-dev.0
- logreader: 8.0.0
- lookup_server_connector: 2.0.0-dev.0
- memories: 9.0.1
- nextcloud_announcements: 7.0.0
- notifications: 8.0.0
- notify_push: 1.4.1
- oauth2: 2.0.0-dev.0
- office: 1.1.0
- password_policy: 7.0.0
- photos: 8.0.0
- privacy: 7.0.0
- profile: 2.0.0-dev.0
- provisioning_api: 2.0.0-dev.0
- registration: 3.1.0
- related_resources: 6.0.0
- serverinfo: 7.0.0
- settings: 2.0.0-dev.0
- sharebymail: 2.0.0-dev.0
- sharing: 1.0.4
- support: 7.0.0
- text: 9.0.0
- theming: 3.0.0-dev.0
- twofactor_backupcodes: 2.0.0-dev.0
- twofactor_totp: 17.1.0
- updatenotification: 2.0.0-dev.0
- viewer: 8.0.0
- webhook_listeners: 2.0.0-dev.0
- workflowengine: 3.0.0-dev.0
Nextcloud Signing status
No errors have been found.
Nextcloud Logs
{"reqId":"<redacted>","level":3,"time":"2026-09-21T16:14:26+02:00","remoteAddr":"<redacted-ip>","user":"<redacted-user>","app":"core","method":"PUT","url":"/remote.php/dav/uploads/<redacted-user>/<upload-id>/000001","scriptName":"/remote.php","message":"unable to rename, source directory is not writable : uploads/<upload-id>","userAgent":"curl/8.21.0","version":"35.0.0.10","data":{"app":"core"}}
{"reqId":"<redacted>","level":3,"time":"2026-09-21T16:14:26+02:00","remoteAddr":"<redacted-ip>","user":"<redacted-user>","app":"webdav","method":"PUT","url":"/remote.php/dav/uploads/<redacted-user>/<upload-id>/000001","scriptName":"/remote.php","message":"renaming part file to final file failed $renameOkay: false, $fileExists: false)","userAgent":"curl/8.21.0","version":"35.0.0.10","data":{"app":"webdav","source_storage":"home::<redacted-user>","target_storage":"home::<redacted-user>","source_internal_path":"uploads/<upload-id>/<temporary-part-file>","target_internal_path":"uploads/<upload-id>/000001"}}
{"reqId":"<redacted>","level":3,"time":"2026-09-21T16:14:26+02:00","remoteAddr":"<redacted-ip>","user":"<redacted-user>","app":"webdav","method":"PUT","url":"/remote.php/dav/uploads/<redacted-user>/<upload-id>/000001","scriptName":"/remote.php","message":"Konnte temporäre Datei nicht in die endgültige Datei umbenennen","userAgent":"curl/8.21.0","version":"35.0.0.10","exception":{"Exception":"Sabre\\DAV\\Exception","Message":"Konnte temporäre Datei nicht in die endgültige Datei umbenennen","Code":0,"File":"/config/www/nextcloud/apps/dav/lib/Connector/Sabre/File.php","Line":339}}
Additional info
Environment
- Nextcloud Server: 35.0.0.10 (35.0.0)
- Container: LinuxServer.io Nextcloud Docker container on an Unraid host
- PHP: 8.4.16
- Database: PostgreSQL 16.15
- Web server / reverse proxy: Nginx / SWAG
- Redis is used for file locking
- Server-side encryption: disabled
- User backend: default database backend
files.chunked_upload.max_parallel_count: 1
files.chunked_upload.max_size: 104857600
The reproducer was run through the normal public HTTPS path. The concurrent
requests were deliberately created by curl; this test does not rely on the
Android client to create them.
Observed request sequence
In the 32 MiB test:
- MKCOL upload collection -> HTTP 201
- PUT 000001 (slow request starts)
- PUT 000001 (second request) -> HTTP 201
- MOVE .file -> HTTP 201
- PUT 000001 (slow request completes) -> HTTP 500
- GET final file -> HTTP 200
Immediately before sending the MOVE request, the slow PUT process was
confirmed to still be active.
The slow PUT completed about 50 seconds after the successful MOVE and
returned HTTP 500.
The resulting 32 MiB file was nevertheless complete:
- downloaded size matched the original size
- SHA-256 matched the original payload
The same behaviour was also reproduced independently with a 1 MiB payload.
Related Android issue
I originally noticed a similar request sequence while investigating my
Android Auto Upload issue: nextcloud/android#17671
The Android issue concerns the client-side Auto Upload problem. This server
report is intentionally narrower and only describes the independently
reproducible server response to overlapping PUT requests.
This report does not claim that Nextcloud Server causes the duplicate client
requests. The curl reproducer deliberately creates the overlap and is only
intended to isolate the server-side response to that race condition.
Bug description
While investigating an Android Auto Upload problem, I noticed a server-side
behaviour that I was able to reproduce independently of the Android client.
If two PUT requests for the same chunk of the same chunked-upload collection
overlap, and one request finishes before the upload is finalized with MOVE,
the still-running PUT later returns HTTP 500.
The MOVE itself succeeds and the resulting file is complete and correct.
I reproduced this twice:
In the 32 MiB test, the first PUT was confirmed to still be running when the
MOVE was performed.
I am not sure whether HTTP 500 is considered the expected response for this
race condition, so I reduced it to a client-independent curl reproducer.
Steps to reproduce
Create a chunked upload collection:
MKCOL /remote.php/dav/uploads/{user}/{upload-id}Result: HTTP 201
Start a PUT to chunk
000001and deliberately throttle the request so thatit remains active.
While the first PUT is still active, start a second PUT of the same chunk:
PUT /remote.php/dav/uploads/{user}/{upload-id}/000001Result: HTTP 201
Confirm that the first PUT is still running.
Finalize the upload:
MOVE /remote.php/dav/uploads/{user}/{upload-id}/.filewith:
Destination: /remote.php/dav/files/{user}/{target-file}OC-Total-Length: {payload-size}Result: HTTP 201
Wait for the first, still-running PUT to finish.
Result: HTTP 500
Download the final file.
Result: HTTP 200. File size and SHA-256 match the original payload.
Expected behavior
I am not sure which WebDAV status code is preferred when an upload collection
has already been successfully finalized while another PUT to that collection
is still in progress.
However, returning HTTP 500 and logging "source directory is not writable"
seems misleading in this situation because the storage is writable, the MOVE
completed successfully, and the final file exists with the correct content.
Ideally this race should be handled without reporting an internal server
error.
Nextcloud Server version
35
Operating system
Other
PHP engine version
PHP 8.4
Web server
Nginx
Database engine version
PostgreSQL
Is this bug present after an update or on a fresh install?
Upgraded to a MAJOR version (ex. 31 to 32)
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
{ "system": { "datadirectory": "***REMOVED SENSITIVE VALUE***", "filesystem_check_changes": 0, "instanceid": "***REMOVED SENSITIVE VALUE***", "passwordsalt": "***REMOVED SENSITIVE VALUE***", "secret": "***REMOVED SENSITIVE VALUE***", "trusted_domains": { "1": "cloud.example.com", "2": "example.com", "3": "127.0.0.1", "4": "localhost", "7": "<internal-ip>", "8": "nextcloud", "9": "<internal-container-ip>", "10": "<internal-container-ip>" }, "tempdirectory": "/temp", "skeletondirectory": "/config/custom_skeleton", "supportedDatabases": [ "pgsql" ], "dboptions": { "2": 30, "3": 2 }, "overwrite.cli.url": "https://cloud.example.com", "overwritehost": "cloud.example.com", "overwriteprotocol": "https", "overwritecondaddr": "^<internal-container-subnet>$", "has_internet_connection": true, "dbtype": "pgsql", "version": "35.0.0.10", "dbname": "***REMOVED SENSITIVE VALUE***", "dbhost": "***REMOVED SENSITIVE VALUE***", "dbport": "", "dbtableprefix": "oc_", "dbuser": "***REMOVED SENSITIVE VALUE***", "dbpassword": "***REMOVED SENSITIVE VALUE***", "installed": true, "default_phone_region": "<redacted>", "default_language": "<redacted>", "default_locale": "<redacted>", "maintenance": false, "filelocking.enabled": true, "filelocking.debug": false, "filelocking.ttl": 43200, "apps_paths": [ { "path": "/app/www/public/apps", "url": "/apps", "writable": false }, { "path": "/config/www/nextcloud/apps", "url": "/custom_apps", "writable": true } ], "mail_from_address": "***REMOVED SENSITIVE VALUE***", "mail_smtpmode": "smtp", "mail_sendmailmode": "smtp", "mail_domain": "***REMOVED SENSITIVE VALUE***", "mail_smtphost": "***REMOVED SENSITIVE VALUE***", "mail_smtpport": "587", "mail_smtpauth": true, "mail_smtpname": "***REMOVED SENSITIVE VALUE***", "mail_smtppassword": "***REMOVED SENSITIVE VALUE***", "mail_smtpauthtype": "LOGIN", "mail_smtptimeout": 30, "mail_smtp_address_family": "ipv4", "ffmpeg": "/usr/bin/ffmpeg", "enable_previews": true, "preview_format": "webp", "updater.release.channel": "stable", "loglevel": 2, "log_query_overhead": false, "updater.secret": "***REMOVED SENSITIVE VALUE***", "upgrade.disable-web": true, "maintenance_window_start": 1, "defaultapp": "files", "forbidden_filename_characters": [ "\\", "/" ], "preview_max_memory": 1024, "preview_max_x": 2048, "preview_max_y": 2048, "preview_max_scale_factor": 1, "preview_render_max_scale": 1, "preview_max_filesize_image": 50, "preview_quality": 85, "preview_standard_res": "64 256 512 1024 2048", "data-fingerprint": "<redacted>", "asset-pipeline.enabled": false, "memlimit": "4G", "htaccess.RewriteBase": "/", "x_permitted_cross_domain_policies": "none", "appstoreenabled": true, "versions_retention_obligation": "auto, 3", "shareapi_allow_share_dialog_user_enumeration": false, "preview_ffmpeg_path": "/usr/bin/ffmpeg", "lorelejay.preview_on_demand": false, "logfilemode": 436, "Dav": { "timeout": 7200 }, "logtimezone": "<redacted>", "log_type": "file", "logfile": "/data/nextcloud.log", "allow_local_remote_servers": false, "proxy_proxies": 0, "logformat": "", "log_rotate_size": 104857600, "memories.db.triggers.fcu": true, "memories.exiftool": "/app/www/public/apps/memories/bin-ext/exiftool-amd64-musl", "show_hidden": true, "airlock.ignore_nomedia": true, "logperm": 436, "preview_max_filesize_executable": 50, "preview_max_scale": 1, "preview_jpeg_resample": true, "image_magick_resample": true, "opcache_optimization_level": 2147467263, "enabledPreviewProviders": [ "OC\\Preview\\WebP", "OC\\Preview\\HEIC", "OC\\Preview\\JPEG", "OC\\Preview\\PNG", "OC\\Preview\\GIF", "OC\\Preview\\BMP", "OC\\Preview\\XBitmap", "OC\\Preview\\Movie", "OC\\Preview\\PDF", "OC\\Preview\\MP3", "OC\\Preview\\TXT", "OC\\Preview\\MarkDown", "OC\\Preview\\Krita", "OC\\Preview\\SVG", "OC\\Preview\\Image", "OC\\Preview\\TIFF", "OC\\Preview\\Font", "OC\\Preview\\OpenDocument", "OC\\Preview\\Imagick" ], "preview_generation_max_instruction_count": 2000000, "serverid": "<redacted>", "mail_smtpstreamoptions": { "ssl": { "allow_self_signed": false, "verify_peer": true, "verify_peer_name": true } }, "memcache.local": "\\OC\\Memcache\\APCu", "memcache.distributed": "\\OC\\Memcache\\Redis", "memcache.locking": "\\OC\\Memcache\\Redis", "redis": { "host": "***REMOVED SENSITIVE VALUE***", "port": 6379, "password": "***REMOVED SENSITIVE VALUE***", "timeout": 0 }, "memories.vod.disable": false, "memories.vod.external": true, "memories.vod.ffmpeg": "/usr/bin/ffmpeg", "memories.vod.ffprobe": "/usr/bin/ffprobe", "memories.vod.bind": "", "memories.vod.connect": "<internal-service>:47788", "memories.vod.nvenc": true, "memories.vod.path": "/config/www/nextcloud/apps/memories/bin-ext/go-vod-amd64", "memories.index.path.blacklist": "\\.thumbnails|@Recycle|eaDir", "preview_exclude_folders": [ ".thumbnails", "Thumbnails", "Recycle-Bin", "recyclebin", "@eaDir" ], "preview_concurrency_all": 4, "preview_concurrency_new": 2, "memories.vod.use_gop_size": true, "referrer_policy": "no-referrer-when-downgrade", "check_data_directory_permissions": false, "trusted_proxies": "***REMOVED SENSITIVE VALUE***", "files.chunked_upload.max_parallel_count": 1, "files.chunked_upload.max_size": 104857600 } }List of activated Apps
Nextcloud Signing status
Nextcloud Logs
{"reqId":"<redacted>","level":3,"time":"2026-09-21T16:14:26+02:00","remoteAddr":"<redacted-ip>","user":"<redacted-user>","app":"core","method":"PUT","url":"/remote.php/dav/uploads/<redacted-user>/<upload-id>/000001","scriptName":"/remote.php","message":"unable to rename, source directory is not writable : uploads/<upload-id>","userAgent":"curl/8.21.0","version":"35.0.0.10","data":{"app":"core"}} {"reqId":"<redacted>","level":3,"time":"2026-09-21T16:14:26+02:00","remoteAddr":"<redacted-ip>","user":"<redacted-user>","app":"webdav","method":"PUT","url":"/remote.php/dav/uploads/<redacted-user>/<upload-id>/000001","scriptName":"/remote.php","message":"renaming part file to final file failed $renameOkay: false, $fileExists: false)","userAgent":"curl/8.21.0","version":"35.0.0.10","data":{"app":"webdav","source_storage":"home::<redacted-user>","target_storage":"home::<redacted-user>","source_internal_path":"uploads/<upload-id>/<temporary-part-file>","target_internal_path":"uploads/<upload-id>/000001"}} {"reqId":"<redacted>","level":3,"time":"2026-09-21T16:14:26+02:00","remoteAddr":"<redacted-ip>","user":"<redacted-user>","app":"webdav","method":"PUT","url":"/remote.php/dav/uploads/<redacted-user>/<upload-id>/000001","scriptName":"/remote.php","message":"Konnte temporäre Datei nicht in die endgültige Datei umbenennen","userAgent":"curl/8.21.0","version":"35.0.0.10","exception":{"Exception":"Sabre\\DAV\\Exception","Message":"Konnte temporäre Datei nicht in die endgültige Datei umbenennen","Code":0,"File":"/config/www/nextcloud/apps/dav/lib/Connector/Sabre/File.php","Line":339}}Additional info
Environment
files.chunked_upload.max_parallel_count:1files.chunked_upload.max_size:104857600The reproducer was run through the normal public HTTPS path. The concurrent
requests were deliberately created by curl; this test does not rely on the
Android client to create them.
Observed request sequence
In the 32 MiB test:
Immediately before sending the MOVE request, the slow PUT process was
confirmed to still be active.
The slow PUT completed about 50 seconds after the successful MOVE and
returned HTTP 500.
The resulting 32 MiB file was nevertheless complete:
The same behaviour was also reproduced independently with a 1 MiB payload.
Related Android issue
I originally noticed a similar request sequence while investigating my
Android Auto Upload issue: nextcloud/android#17671
The Android issue concerns the client-side Auto Upload problem. This server
report is intentionally narrower and only describes the independently
reproducible server response to overlapping PUT requests.
This report does not claim that Nextcloud Server causes the duplicate client
requests. The curl reproducer deliberately creates the overlap and is only
intended to isolate the server-side response to that race condition.