Nextcloud Max Upload Size: Fix Error 413 (It's Usually Not PHP)
Nextcloud's "status code 413" upload error comes from the reverse proxy in front of it, not from Nextcloud or PHP. nginx allows 1 MB unless you set client_max_body_size, so raise it (Nextcloud's own example uses 512M). Browser uploads already go up in 100 MB pieces, so PHP's limit rarely matters, and behind a proxy with a fixed cap like Cloudflare's 100 MB, make the pieces smaller with files.chunked_upload.max_size.
When a Nextcloud upload fails with "Error during upload, status code
413", the file isn't too big for Nextcloud. It's too big for the web
server in front of it, usually an nginx reverse proxy. nginx accepts requests of
up to 1 MB unless its config says otherwise, so on its stock settings almost
every real file is refused before Nextcloud sees it. The fix is one line:
client_max_body_size 512M;, then reload nginx.
We tested every step on a fresh Nextcloud 35.0.1 in Docker
(nextcloud:35.0.1-apache), reached through an nginx reverse proxy
(nginx:stable-alpine), the way most people put Nextcloud on their own
domain.
Why does Nextcloud say "status code 413"?
413 means "Request Entity Too Large": a server between your browser and Nextcloud decided the upload was too big. An upload passes three limits on its way in, and any of them can answer 413:
- Your reverse proxy. nginx's
client_max_body_sizedefaults to1m. Its documentation: "If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client." - Apache, inside the Nextcloud image. The image's
APACHE_BODY_LIMITdefaults to 1 GiB (1073741824). - PHP. The image's
PHP_UPLOAD_LIMITdefaults to512M.
In our test, a 40 MB zip uploaded through the proxy on its stock settings failed with "Error during upload, status code 413" and "Unknown error during upload". The proxy's own log said "client intended to send too large body". 40 MB is far under Apache's and PHP's limits; only nginx's 1 MB was smaller.
How do I fix error 413 in nginx?
Add one line to the server block that proxies to Nextcloud, then
reload nginx:
server {
# ...
client_max_body_size 512M;
location / {
proxy_pass http://nextcloud:80;
# ...
}
}
nginx -s reload
512M is the value in Nextcloud's own example nginx configuration.
0 turns nginx's check off entirely. After the change, the same 40 MB
upload went straight in. Nothing in Nextcloud changed.
If you use a different proxy, it has its own setting for the same limit. We only tested nginx here, so we haven't listed the others.
Do I need to raise PHP's upload_max_filesize?
For uploads in the browser, usually not. With nginx at 512M and
PHP at its Docker default of 512M, we uploaded a 1.2 GB file through
the browser without changing anything else. It went past PHP's 512 MB, past
Apache's 1 GiB, and past nginx's 512 MB.
That's because Nextcloud's web interface uploads any file over 100 MiB in pieces. Each piece is its own request, and Nextcloud joins them into one file at the end. Our 1.2 GB file went up as twelve requests of 100 MiB each, so no limit ever saw more than one piece. The admin manual says the same of the desktop app: "The Nextcloud sync client is not affected by these upload limits as it is uploading files in smaller chunks."
The limits still matter to apps that send a whole file in a single request. In our test, a 600 MB file sent in one WebDAV request went through even with PHP's limit at 512 MB, but a 1.2 GB one was refused with 413 by Apache, whose 1 GiB limit applies to every request. To raise it in Docker, set the image's variables:
environment:
- APACHE_BODY_LIMIT=0 # 0 = no limit; the default is 1073741824 (1 GiB)
- PHP_UPLOAD_LIMIT=16G # the default is 512M
Uploads still fail behind Cloudflare. What now?
Some proxies cap every request at a size you can't raise. Cloudflare is the common one: for proxied domains, its Free and Pro plans allow 100 MB per request (Business 200 MB), and "Requests exceeding this limit receive a 413 Request Entity Too Large error." Nextcloud's upload pieces are 100 MiB by default, right at that cap.
We stood in for that by capping our own nginx at 100,000,000 bytes. A 1.2 GB upload failed with status code 413 again, because every 100 MiB piece (104,857,600 bytes) was over the cap. The fix is to make the pieces smaller. The admin manual gives this command, which sets them to 20 MiB:
sudo -E -u www-data php occ config:system:set --type int --value 20971520 files.chunked_upload.max_size
In Docker, run it through the container as the web server's user:
docker exec -u www-data <container> php occ config:system:set files.chunked_upload.max_size --type=integer --value=20971520
Reload the Files page afterwards: the browser reads the piece size when Files
loads. With 20 MiB pieces, the same 1.2 GB upload went through the capped proxy.
The setting is in bytes, and 0 turns chunking off.
Older guides set max_chunk_size with
occ config:app:set files. In Nextcloud 35 that app setting is migrated
to files.chunked_upload.max_size in config.php and then
deleted, so use the system setting.
What if the error isn't 413?
Very large uploads can fail in other ways, such as a timeout. Those show a different error, and the fixes are different. The admin manual's page on big file uploads covers the other settings involved.
Sources
Full video transcript
1
00:00:00,000 --> 00:00:03,136
If your Nextcloud uploads
fail with status code 413,
2
00:00:03,176 --> 00:00:05,396
the file isn't too big for Nextcloud.
3
00:00:05,436 --> 00:00:08,267
It's too big for the web
server in front of it.
4
00:00:08,307 --> 00:00:13,031
That's usually nginx, and on its normal
settings it lets through one megabyte.
5
00:00:13,071 --> 00:00:13,886
I'll fix that,
6
00:00:13,926 --> 00:00:18,528
show you why the PHP setting most guides
point to usually isn't the problem,
7
00:00:18,568 --> 00:00:22,049
and what to do when your proxy
has a cap you can't raise.
8
00:00:22,449 --> 00:00:25,956
This is Nextcloud thirty
five, freshly installed.
9
00:00:25,996 --> 00:00:29,575
It runs in Docker, on a
Linux server I run myself.
10
00:00:29,615 --> 00:00:32,904
In front of it sits nginx,
as a reverse proxy.
11
00:00:32,944 --> 00:00:37,030
That's the usual way to put
Nextcloud on your own domain.
12
00:00:37,070 --> 00:00:39,675
And nginx is on its normal settings.
13
00:00:40,936 --> 00:00:46,617
Let's upload something ordinary. New,
upload files, and a forty megabyte zip.
14
00:00:47,826 --> 00:00:54,771
Error during upload, status code 413.
Forty megabytes, and it's refused.
15
00:00:54,811 --> 00:00:58,983
It looks like Nextcloud
said no. It didn't.
16
00:01:00,234 --> 00:01:04,443
An upload passes three gates on
its way in. First, the proxy.
17
00:01:04,483 --> 00:01:08,901
Then the web server inside the
Nextcloud image, which is Apache.
18
00:01:08,941 --> 00:01:13,916
Then PHP, which runs Nextcloud itself.
Each gate has its own size limit.
19
00:01:13,956 --> 00:01:19,070
In the Docker image, PHP allows 512
megabytes. Apache allows one gigabyte.
20
00:01:19,110 --> 00:01:24,403
Forty megabytes is far under both. So
the gate that refused it is the proxy.
21
00:01:25,722 --> 00:01:29,602
Here's nginx's own
documentation for that limit.
22
00:01:30,810 --> 00:01:34,815
Sets the maximum allowed size
of the client request body.
23
00:01:34,855 --> 00:01:40,178
If a request is bigger, the 413 error
is returned. That's the error we got.
24
00:01:41,422 --> 00:01:44,636
And just above it, the
default. One megabyte.
25
00:01:44,676 --> 00:01:49,337
If your nginx config never sets
this, one megabyte is your limit.
26
00:01:49,377 --> 00:01:52,487
A bigger file never
even reaches Nextcloud.
27
00:01:53,736 --> 00:01:58,817
The fix is one line, in the
nginx server block for Nextcloud.
28
00:01:58,857 --> 00:02:01,168
Client max body size, 512 M.
29
00:02:01,208 --> 00:02:05,954
That's the value in Nextcloud's
own example nginx config.
30
00:02:05,994 --> 00:02:09,520
Then reload nginx, so it reads the change.
31
00:02:12,003 --> 00:02:16,873
Back in Nextcloud. I've added that
line to my proxy, and reloaded it.
32
00:02:19,735 --> 00:02:21,763
Same file, same upload.
33
00:02:26,044 --> 00:02:32,225
This time it's in. Holiday photos, forty
megabytes. Nothing in Nextcloud changed.
34
00:02:32,265 --> 00:02:33,724
Only the proxy did.
35
00:02:34,962 --> 00:02:40,135
Now, most guides say the limit that
matters is PHP's upload setting.
36
00:02:40,175 --> 00:02:46,038
Here, that's 512 megabytes. So let's
upload a file more than twice that size.
37
00:02:46,078 --> 00:02:47,764
A 1.2 gigabyte backup.
38
00:02:49,983 --> 00:02:52,433
It went in. 1.2 gigabytes.
39
00:02:52,473 --> 00:02:57,509
Past PHP's 512 megabytes,
past Apache's one gigabyte,
40
00:02:57,549 --> 00:03:00,996
and past the 512 we just gave nginx.
41
00:03:02,248 --> 00:03:03,003
Here's why.
42
00:03:03,043 --> 00:03:05,244
When you upload in the browser,
43
00:03:05,284 --> 00:03:10,449
Nextcloud cuts any file over 100
megabytes into pieces of 100 megabytes.
44
00:03:10,489 --> 00:03:16,449
Each piece is its own request. At the end,
Nextcloud joins them back into one file.
45
00:03:16,489 --> 00:03:22,160
So no gate ever sees more than one piece.
That backup went in as twelve pieces.
46
00:03:22,200 --> 00:03:28,015
PHP's limit, and Apache's, still matter
to apps that send a whole file in one go.
47
00:03:28,055 --> 00:03:30,584
A browser upload isn't one of them.
48
00:03:31,909 --> 00:03:35,744
There's one setup where raising
the limit isn't up to you.
49
00:03:35,784 --> 00:03:39,486
Some proxies cap every request,
and you can't change it.
50
00:03:39,526 --> 00:03:42,025
Cloudflare is the one people run into.
51
00:03:42,065 --> 00:03:46,435
On its free and pro plans, a request
can be at most 100 megabytes.
52
00:03:46,475 --> 00:03:51,821
Nextcloud's pieces are 100 megabytes too,
right at the cap. There's no headroom.
53
00:03:54,329 --> 00:03:57,938
To show it, I've capped my
own proxy at 100 megabytes.
54
00:03:57,978 --> 00:04:02,235
It's a stand-in, not Cloudflare
itself. Now another big backup.
55
00:04:03,508 --> 00:04:05,088
Status code 413 again.
56
00:04:05,128 --> 00:04:10,061
Every piece is a little over my
cap, so every piece is turned away.
57
00:04:11,294 --> 00:04:14,635
You can't raise the cap, so
make the pieces smaller.
58
00:04:14,675 --> 00:04:17,626
One command on the server
sets the piece size.
59
00:04:17,666 --> 00:04:22,698
This value is the example in Nextcloud's
admin manual. About twenty megabytes.
60
00:04:22,738 --> 00:04:26,640
In Docker, run it through docker
exec, as the www-data user.
61
00:04:29,290 --> 00:04:34,928
I've run it. The browser reads the piece
size when Files loads, so reload the page.
62
00:04:36,138 --> 00:04:38,374
And upload the same backup again.
63
00:04:41,338 --> 00:04:46,761
In it goes. Same proxy, same cap.
The pieces are small enough now.
64
00:04:48,597 --> 00:04:52,014
So. Status code 413 is
your proxy, not Nextcloud.
65
00:04:52,054 --> 00:04:57,588
In nginx, set client max body size.
Nextcloud's own example uses 512 megabytes.
66
00:04:57,628 --> 00:05:03,021
PHP's limit rarely matters in the browser,
because big files go up in pieces.
67
00:05:03,061 --> 00:05:07,890
And if your proxy has a cap you
can't raise, make the pieces smaller.
68
00:05:07,930 --> 00:05:12,587
The exact lines for nginx and Docker
are on the page linked below.