Chunked transfers lead to 0 byte files #7995
Description
Activity
After some more testing I've noticed that it's even worse. It does not matter if you create a 0 byte file prior updating it. Basically all
PUToperations with a chunked transfer encoding lead to 0 byte files in low latency and high bandwidth environments for files that are greater than a certain size (see above). In my local environment it's easy to replicate with a simple curl command. E.g.curl -v -X PUT --header "Transfer-Encoding: chunked" -d @testfile.bin "http://ubuntu.local/remote.php/webdav/testfile.bin" -u admin:adminReacted by John Daktylidis, David Kocher, Navin Francis Shajan and Torsten Grote- addedstaleTicket or PR with no recent activityTicket or PR with no recent activity
on Jun 20, 2018 - removedstaleTicket or PR with no recent activityTicket or PR with no recent activity
on Jul 5, 2018 I too am having this issue with webdav.
After disabling encryption and sniffing the traffic going to and from the nextcloud webserver (nginx 1.14.0 in my case), I too came to the conclusion, that after a PUT command with chunked transfer encoding, nextcloud responses with 204 no content and creates only 0 byte files.I noticed this behavior when trying to export my Kodi library via webdav to nextcloud.
I can also provide a sanitized HTTP communication if needed, but I guess that will not help much.
I just tested on nextcloud 15 with a 700 kb image. 256 kb of the image made it to the server. a 7.5 mb ODP file was also cut in half - 3.3 mb on the server.
curl -v -X PUT --header "Transfer-Encoding: chunked" -d @test.odp "http://127.0.0.1/nextcloud-15/remote.php/webdav/test.odp" -u jos:jos * Trying 127.0.0.1... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 80 (#0) * Server auth using Basic with user 'jos' > PUT /nextcloud-15/remote.php/webdav/test.odp HTTP/1.1 > Host: 127.0.0.1 > Authorization: Basic am9zOmpvcw== > User-Agent: curl/7.62.0 > Accept: */* > Transfer-Encoding: chunked > Content-Type: application/x-www-form-urlencoded > Expect: 100-continue > < HTTP/1.1 100 Continue * Signaling end of chunked upload via terminating chunk. < HTTP/1.1 201 Created < Date: Thu, 03 Jan 2019 11:22:50 GMT < Server: Apache < X-Powered-By: PHP/7.3.0 < Set-Cookie: oczswzpgpvdq=9qbdh7bhvlq6s9um76vqfs7dlg; path=/nextcloud-15; HttpOnly < Expires: Thu, 19 Nov 1981 08:52:00 GMT < Cache-Control: no-store, no-cache, must-revalidate < Pragma: no-cache < Set-Cookie: oc_sessionPassphrase=I1gqnptmzWjmuBJhZqrfPOeNr6LIhTAn6OWTsFxQhflPr2EuxY2LtSmdoIMc0bz4ehfVuMBRmLO%2FZBBQG6FEDfgc0Q7qupNRWiHZPR%2BxESiNJg5Vh1%2Fajn6geMMRJNWv; path=/nextcloud-15; HttpOnly < Content-Security-Policy: default-src 'none'; < X-Frame-Options: SAMEORIGIN < X-XSS-Protection: 1; mode=block < X-Content-Type-Options: nosniff < X-Robots-Tag: none < X-Download-Options: noopen < X-Permitted-Cross-Domain-Policies: none < Referrer-Policy: no-referrer < Set-Cookie: nc_sameSiteCookielax=true; path=/nextcloud-15; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax < Set-Cookie: nc_sameSiteCookiestrict=true; path=/nextcloud-15; httponly;expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict < Set-Cookie: oczswzpgpvdq=pj5kbp17hlf3btfob60d2meh7q; path=/nextcloud-15; HttpOnly < Set-Cookie: cookie_test=test; expires=Thu, 03-Jan-2019 12:22:50 GMT; Max-Age=3600 < OC-FileId: 00001151oczswzpgpvdq < Content-Length: 0 < ETag: "7ef58d6f933a4e3387fdf1418f188772" < OC-ETag: "7ef58d6f933a4e3387fdf1418f188772" < Content-Type: text/html; charset=UTF-8 < * Connection #0 to host 127.0.0.1 left intact- added0. Needs triagePending check for reproducibility or if it fits our roadmapPending check for reproducibility or if it fits our roadmap
on Jan 3, 2019 84 remaining items
I trust the nextcloud-aio-apache image is already properly configured to avoid this type of issue, yes?
It uses Apache and for Apache we already fixed this in the
.htaccessa long time ago.- added a commit that references this issue
on Sep 4, 2025 Commenting on the integrity verification: HTTP does provide this kind of thing with the Content-MD5 header (not implemented by NextCloud AFAIK), and NextCloud also has their own non-standard header called
OC-Checksum.But I'm not sure that this is used by the NextCloud client for multi-part uploads?
@bohwaz no the
Content-MD5header is not part of HTTP anymore, see Appendix B:
https://www.rfc-editor.org/rfc/rfc7231So yes Nextcloud has its own header for downloads (OC-Checksum).
- added a commit that references this issue
on Oct 30, 2025 I ran into similar problem when uploading bigger file via browser. When the file was like 100MB, it was reported as 0 B, but in the object storage (I have Swift) was correct.
This happens when using Safari on my Mac. The first upload of a bigger file (=multipart upload) leads to 0 size in metadata, correct size in the storage. The 2nd upload (rewrite) results in correct metadata size.
When using Chrome, it was always ok - even the 1st upload was ok.
I didn't found the exact reason why 2 different browsers lead to different results but found, that in the code is a place, where based on
size === nullthe real size is calculated. But for Safari a zero arrives ("0"), even fstat says "bigger than zero". I added the following "safety patch" that solves the issue:Maybe this helps:
--- lib/private/Files/ObjectStore/ObjectStoreStorage.php.orig 2026-01-12 15:53:11 +++ lib/private/Files/ObjectStore/ObjectStoreStorage.php 2026-01-12 15:55:09 @@ -457,6 +457,19 @@ } public function writeStream(string $path, $stream, ?int $size = null): int { + $stats = is_resource($stream) ? @fstat($stream) : null; + $fstatSize = is_array($stats) ? ($stats['size'] ?? null) : null; + + if ($size === 0 && is_int($fstatSize) && $fstatSize > 0) { + $this->logger->error('ObjectStoreStorage::writeStream forcing size=null (size_arg=0 but fstat_size>0)', [ + 'app' => 'objectstore', + 'path' => $path, + 'size_arg' => $size, + 'fstat_size' => $fstatSize, + ]); + $size = null; + } + if ($size === null) { $stats = fstat($stream); if (is_array($stats) && isset($stats['size'])) {Hi, we have some code since a while to prevent this bug from happening now in our .htaccess file:
Lines 178 to 189 in 7f71b46
# Clients like xDavv5 on Android, or Cyberduck, use chunked requests. # When FastCGI or FPM is used with apache, requests arrive to Nextcloud without any content. # This leads to the creation of empty files. # The following directive will force the problematic requests to be buffered before being forwarded to Nextcloud. # This way, the "Transfer-Encoding" header is removed, the "Content-Length" header is set, and the request content is proxied to Nextcloud. # Here are more information about the issue: # - https://docs.cyberduck.io/mountainduck/issues/fastcgi/ # - https://docs.nextcloud.com/server/latest/admin_manual/issues/general_troubleshooting.html#troubleshooting-webdav <IfModule mod_setenvif.c> SetEnvIfNoCase Transfer-Encoding "chunked" proxy-sendcl=1 </IfModule> Can you please retest if this is still happening with the latest Nextcloud releases? Thanks in advance!
- added0. Needs triagePending check for reproducibility or if it fits our roadmapPending check for reproducibility or if it fits our roadmapand removed1. to developAccepted and waiting to be taken care ofAccepted and waiting to be taken care of
on Jan 29, 2026 @szaimen yes it still happens in e.g. Nginx.
This is a upstream PHP problem as they refuse to forward data streams in PHP FPM when no content length is available.
Other FastCGI solutions do this and Nginx as well as Apache also support this - just PHP FPM is broken.Reacted by Simon L.
We hit the annoying 0 byte files issue when using a
PUToperation with a chunked transfer encoding to modify an existing 0 byte file. After successfully executing thePUTthe server replies with a 204 but the file is still empty. Not sure if this is a NC or sabre/dav issue.I'm using nginx 1.13.8 as a webserver (nginx 1.10.3 doesn't work either). My nginx configuration is quite default. The relevant part:
Some observations:
fastcgi_request_buffering offtofastcgi_request_buffering onsolves the issue but this is not an option for large streamed files.Background: I'm a developer of Mountain Duck which uses the create/update file pattern described here http://sabre.io/dav/0bytes/. According this document nginx in a newer version should work fine. We have several users hitting this issue though.
Steps to reproduce
Expected behaviour
Files has updated content and correct size
Actual behaviour
Remote file is not touched at all and you still see 0 bytes
Server configuration
Operating system:
Ubuntu 16
Web server:
nginx
Database:
MariaDB
PHP version:
7.0.22
Nextcloud version: (see Nextcloud admin page)
12.0.4
Updated from an older Nextcloud/ownCloud or fresh install:
Fresh
Where did you install Nextcloud from:
Official download