Can only upload small (<500kB) files over internet, but over LAN works fine

Device: Odroid HC1
Nextcloud version: 13.0.0
Operating system and version: Ubuntu 16.04.4 LTS (32 bit)
Apache or nginx version: nginx/1.10.3
PHP version: 7.0

The issue you are facing:
Last week I’ve been trying to get Nextcloud to work on my Odroid HC1. However I keep running into the same problem time and again.

Everything works fine up to the point where I try to upload a file from outside the LAN. Over the internet only the first few hundred kilobytes come through, after which the upload fails. This happens with both the web interface and the Windows client. Via LAN everything works fine, even large files.

All file size limits are set at 2 GB, external ip added to trusted domains in config.php and ports on the router are forwarded. I have this issue with both apache as well as nginx. Also tested with device in router DMZ, etc.

Who has seen this before or can point me in the right direction?

Is this the first time you’ve seen this error? (Y/N): Y

Steps to replicate it:

  1. Install Nextcloud
  2. Add external ip to trusted domains
  3. Forward ports in router
  4. Upload file from outside LAN

The output of your Nextcloud log in Admin > Logging:

Fatal	webdav	Sabre\DAV\Exception\BadRequest: expected filesize 504145 got 344064

    /var/www/html/nextcloud/apps/dav/lib/Connector/Sabre/Directory.php - line 151: OCA\DAV\Connector\Sabre\File->put(Resource id #17)
    /var/www/html/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php - line 1096: OCA\DAV\Connector\Sabre\Directory->createFile('34431561983_af8...', Resource id #17)
    /var/www/html/nextcloud/3rdparty/sabre/dav/lib/DAV/CorePlugin.php - line 525: Sabre\DAV\Server->createFile('34431561983_af8...', Resource id #17, NULL)
    [internal function] Sabre\DAV\CorePlugin->httpPut(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
    /var/www/html/nextcloud/3rdparty/sabre/event/lib/EventEmitterTrait.php - line 105: call_user_func_array(Array, Array)
    /var/www/html/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php - line 479: Sabre\Event\EventEmitter->emit('method PUT', Array)
    /var/www/html/nextcloud/3rdparty/sabre/dav/lib/DAV/Server.php - line 254: Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
    /var/www/html/nextcloud/apps/dav/appinfo/v1/webdav.php - line 80: Sabre\DAV\Server->exec()
    /var/www/html/nextcloud/remote.php - line 164: require_once('/var/www/html/n...')

Log is full with these errors, all at different filesizes:

Fatal	webdav	Sabre\DAV\Exception\BadRequest: expected filesize 504145 got 352256
Fatal	webdav	Sabre\DAV\Exception\BadRequest: expected filesize 690080 got 491520
Fatal	webdav	Sabre\DAV\Exception\BadRequest: expected filesize 1129816 got 598016
Fatal	webdav	Sabre\DAV\Exception\BadRequest: expected filesize 10485760 got 540672

The output of your config.php file in /path/to/nextcloud (make sure you remove any identifiable information!):

$CONFIG = array (
  'instanceid' => 'xxxxxxxxxxxx',
  'passwordsalt' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  'trusted_domains' => 
  array (
    0 => '',
    1 => '',
  'datadirectory' => '/media/hdd/nextcloud/data',
  'overwrite.cli.url' => '',
  'dbtype' => 'mysql',
  'version' => '',
  'dbname' => 'nextcloud',
  'dbhost' => 'localhost:3306',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'xxxx',
  'dbpassword' => 'xxxxxxxxxxxxxxxxxxxxxxxx',
  'installed' => true,
  'memcache.local' => '\OC\Memcache\APCu',

The output of your Apache/nginx/system log in /var/log/____:

No errors here.

Alright I think I’ve found the problem. Please correct me if I’m wrong.

On the local network -> request local address (say -> router connects you to the right address

On another network -> request external address (123.456.78.90) -> connect to router -> port forward -> right address

Back on the local network -> request external address (123.456.78.90) -> router routes to itself and doesn’t know where to go :sweat_smile:

Although it does connect at first, but is unable to transmit a lot of data. Adding a custom DNS, so the external address get resolved to the local address on the local network, should work I think. Unfortunately this is not possible with the current router.

Solution I’m trying out now, created a subdomain on my website with DNS subdomain -> external address. This should work I think…

Edit: well after configuring sub domain, ssl, and everything it still fails and I can’t figure out what’s going wrong here :pensive:. So please let me know if you have an idea…

port forwarding from your routers !!!

edit nat/pat rules and create the correct ports to ports links, like this

Ports are forwarded, and I can make a connection. However, all uploads fail after the first ~300kB if they are done on the local network.

Uploading from outside the network, or to the local ip works.

have you tried to desable your memcache.local
APCu writes can degrade substantially if storage becomes fragmented, so be careful if you both store lots of data and alter it frequently.

Thanks, I’ve tried that, but made no difference.

Meanwhile I think I’ve found the culprit. There appears to be a known bug in the NAT loopback of the router, so that could explain this strange behavior. Since the router is issued by my ISP I will contact them to find a solution/replacement.

Had the same problem when configuring nginx to work as a reverse proxy.
If you do have a reverse proxy confuration this should fix it, if not then try it anyways.

In your nginx configuration file add the following:

server {
client_max_body_size 16000m;
location *some location* {
    proxy_max_temp_file_size 8192m;
    proxy_set_header Connection "Keep-Alive";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

You can change it by your preferences…
I hope this helps :smile:

1 Like

Problem is the router not hairpinning correctly. So reverse proxy should work as long as the proxy is not on the same LAN I think.

So something like this:
Client request ===> ( => reverse proxy) ===> (router => nextcloud_server)

I’ll have to see with the hosting provider if its possible to set up a proxy. But easiest option is still changing the router for something that works in my opinion.

You should change the router path. It may work because I have done the same thing with my router. You may also take help from Wii error code 51330. They will help you out quickly.

I added the lines

    client_max_body_size 16000m;
    proxy_max_temp_file_size 8192m;
    proxy_set_header Connection "Keep-Alive";

In the following way:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;

ssl_certificate /etc/letsencrypt/live/address.of.server/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/address.of.server/privkey.pem;

ssl_stapling on;
ssl_stapling_verify on;

add_header Strict-Transport-Security "max-age=31536000";

access_log /var/log/nginx/sub.log combined;

client_max_body_size 16000m;


location /.well-known {
    alias /var/www/address.of.server/.well-known;

location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_max_temp_file_size 8192m;
    proxy_set_header Connection "Keep-Alive";


And that solved the problem, thanks a bunch! Was fiddling with this for quite some hours.

1 Like

just in case, someone has a similar issue, which is not solved with with this example.

Try Fixing nginx client_body permission. This was, at least for me, a necessary additional step.