258

nginx keeps saying client intended to send too large body. Googling and RTM pointed me to client_max_body_size. I set it to 200m in the nginx.conf as well as in the vhost conf, restarted Nginx a couple of times but I'm still getting the error message.

Did I overlook something? The backend is php-fpm (max_post_size and max_upload_file_size are set accordingly).

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
q_no
  • 2,589
  • 2
  • 15
  • 3
  • 16
    In case anyone else googles this: Nginx 1.1.19 (on Ubuntu 12.04) *seems* to ignore client_max_body_size in the 'http' directive, although it's fine with it in 'server'. This seems to have been introduced in an update in the last 6 months or so, because for me the same config file on the same server used to work. – Dave Apr 10 '14 at 11:42
  • 5
    There is problem with client_max_body_size on SSL enabled. I just got same problem on lasted nginx version and it ignores this directive in secure connections. Still looking for solution. – Neolo Mar 01 '13 at 20:15
  • 2
    @Dave and if you come here in 2018, this seems fixed — `client_max_body_size` in the `http` section has the expected effect with nginx version 1.14.1 – DomQ Nov 20 '18 at 17:28
  • This checks the content length header (at least in 1.4.6), so if a large file is uploaded with unset content length, or content length set to a value less than the max body size, it will not trigger the HTTP 413 – Charles L. Nov 27 '18 at 18:25

16 Answers16

156

Following nginx documentation, you can set client_max_body_size 20m ( or any value you need ) in the following context:

context: http, server, location
Day
  • 9,465
  • 6
  • 57
  • 93
nembleton
  • 2,392
  • 1
  • 18
  • 20
  • 25
    It didn't work for me in location, worked in the server context. Not sure if it was being overridden, can't say. – Dipen Jun 12 '12 at 10:30
  • @Dipen: Interesting. What version of NGinx do you have? – nembleton Jun 12 '12 at 12:53
  • 12
    Ditto what Dipen said, except I can't get it in the server{} or location{} blocks... it only works in the http{} context. Odd – Robbie Nov 02 '12 at 18:47
  • 5
    I can confirm that it only works on nginx/1.4.1 running on Debian GNU/Linux 7.1 (wheezy) in http{} section. – Fernando Kosh Nov 06 '13 at 04:08
  • 2
    Confirming the setting fails when setting on `http` or `location` settings. Works when set on `server` level. nginx/1.4.4 – AlbertEngelB Jan 27 '14 at 14:53
  • @Dropped.on.Caprica Following the documentation it should work on 3 levels. Maybe you have a counter configuration somewhere? – nembleton Jan 27 '14 at 15:01
  • @nembleton Not sure. I added it to `nginx.conf` at `http` and it failed. I checked `sites-enabled/sites-available` and it wasn't set in any of those configuration files either. It only worked for me after adding it to the specific `sites-enabled` configuration on the `server` level. If I tried it in the `location` area, it would fail as well. Any other place that setting could be set at? EDIT: And this is pretty much a clean install as well. – AlbertEngelB Jan 27 '14 at 15:03
  • @RobC interesting. The doc mentions 'm'. What system are you on? – nembleton Jul 08 '15 at 21:48
  • At location level all I can do is reduce the value and not increase it. Ubuntu 16.04.1 LTS – Geza Turi Dec 05 '16 at 03:56
  • Have the same with 1.10.1 can reduce file size less than 1m, but can't increase that. So I can use 500k, 600k, but not a 100M or 100m. Ubuntu 16 – d7p4x Jul 23 '17 at 12:36
141

NGINX large uploads are successfully working on hosted WordPress sites, finally (as per suggestions from nembleton & rjha94)

I thought it might be helpful for someone, if I added a little clarification to their suggestions. For starters, please be certain you have included your increased upload directive in ALL THREE separate definition blocks (server, location & http). Each should have a separate line entry. The result will like something like this (where the ... reflects other lines in the definition block):

http {
    ...
    client_max_body_size 200M;
}    

(in my ISPconfig 3 setup, this block is in the /etc/nginx/nginx.conf file)

server {
    ...
    client_max_body_size 200M;
}

location / {
    ...
    client_max_body_size 200M;
} 

(in my ISPconfig 3 setup, these blocks are in the /etc/nginx/conf.d/default.conf file)

Also, make certain that your server's php.ini file is consistent with these NGINX settings. In my case, I changed the setting in php.ini's File_Uploads section to read:

upload_max_filesize = 200M

Note: if you are managing an ISPconfig 3 setup (my setup is on CentOS 6.3, as per The Perfect Server), you will need to manage these entries in several separate files. If your configuration is similar to one in the step-by-step setup, the NGINX conf files you need to modify are located here:

/etc/nginx/nginx.conf
/etc/nginx/conf.d/default.conf 

My php.ini file was located here:

/etc/php.ini

I continued to overlook the http {} block in the nginx.conf file. Apparently, overlooking this had the effect of limiting uploading to the 1M default limit. After making the associated changes, you will also want to be sure to restart your NGINX and PHP FastCGI Process Manager (PHP-FPM) services. On the above configuration, I use the following commands:

/etc/init.d/nginx restart
/etc/init.d/php-fpm restart
jadik
  • 1,826
  • 1
  • 13
  • 6
  • 30
    I would suggest you use `/etc/init.d/nginx reload` instead. This has added benefits such as 'if the config is wrong' NginX won't stop functioning. – Hengjie Feb 06 '13 at 22:46
  • Thank you this was really helpful for me! Solved my problem after hacking around with lots of different php.ini file settings etc. – Yos Apr 05 '13 at 10:08
  • Lowercase m worked for us. client_max_body_size 100m; – so_mv Jul 01 '14 at 19:34
  • 20
    @Hengjie I would recommend using `nginx -t` (tests the configuration file syntax) and then `nginx -s reload` (does the actual reload) instead. – Anoyz Mar 06 '15 at 11:02
  • Just need to point out that in my vagrant box there were two ini files - /etc/php5/cli/php.ini and /etc/php5/fpm/php.ini and Symfony's loaded configuration was the fpm one. So don't forget to edit this one. – Jalal Mar 09 '16 at 13:11
  • In my case you only need to edit the `http { } ` part. I followed your approach and then out of curiosity I removed the directive from `server {}` and `location {} ` and the setting was still valid. – benjaminz May 10 '16 at 19:16
  • This does work, but you must run ```sudo service php5-fpm restart && sudo service nginx restart```. I was able to set just the http {} block, I didn't need to set the server {} or location {} blocks for included virtual hosts. BUT the config won't reload until you restart both php and nginx, so as a rule I always run the above command if I change either nginx.conf or php.ini. – Zack Morris Jun 03 '16 at 01:17
  • For PHP7, Ubuntu 16, the service is called `php7.0-fpm`, not `php-fpm` or `php7-fpm`. Maybe there's some Ubuntu setting that'd have created a 'link' from `php-fpm` to `php7.0-fpm` that I'm unaware of. – sameers Jan 23 '17 at 18:10
  • Great solution, this fixed for me in Heroku using NodeJS/Nginx. I'm my case i'm using AdonisJS, and you have to configure the limit: '200mb' and the maxSize: '200mb' in the bodyParser.js config file and finally accept the file size in your code request.file('file', {maxSize: '200mb'}); – Juan Ricardo May 15 '18 at 16:17
  • If you are already limiting the upload size in `php.ini` then you can disable the nginx 'Content-length' header being set by setting `client_max_body_size` to `0`. – holmberd Nov 08 '18 at 17:02
  • Similar to the earlier comment I found that adding only to the `location` block was enough. – Arnold Schrijver Apr 11 '19 at 11:59
  • Do we have an option that unlimited size? – Thach Huynh Nov 11 '20 at 10:11
  • It doesn't work in my setup. I have Nginx as a reverse proxy for my ExpressJs (NodeJs) based API server. Nginx uses below 2 config files where I've added this entry /etc/nginx/nginx.conf and /etc/nginx/conf.d/ssl.conf so, basically the ssl.conf is getting included in the main nginx.conf for SSL enabled traffic. Any idea why it won't work? My Nginx version is 1.14.1 and it's running on RedHat 7 host – Dev Nov 17 '21 at 08:25
79

As of March 2016, I ran into this issue trying to POST json over https (from python requests, not that it matters).

The trick is to put "client_max_body_size 200M;" in at least two places http {} and server {}:

1. the http directory

  • Typically in /etc/nginx/nginx.conf

2. the server directory in your vhost.

  • For Debian/Ubuntu users who installed via apt-get (and other distro package managers which install nginx with vhosts by default), thats /etc/nginx/sites-available/mysite.com, for those who do not have vhosts, it's probably your nginx.conf or in the same directory as it.

3. the location / directory in the same place as 2.

  • You can be more specific than /, but if its not working at all, i'd recommend applying this to / and then once its working be more specific.

Remember - if you have SSL, that will require you to set the above for the SSL server and location too, wherever that may be (ideally the same as 2.). I found that if your client tries to upload on http, and you expect them to get 301'd to https, nginx will actually drop the connection before the redirect due to the file being too large for the http server, so it has to be in both.

Recent comments suggest that there is an issue with this on SSL with newer nginx versions, but i'm on 1.4.6 and everything is good :)

J.J
  • 3,459
  • 1
  • 29
  • 35
  • 4
    The documentation states the default as "1m" which turned out to be 1 megabyte - not 1 megabit. I think - though I haven't yet tested it - it's always megabyte. – Thomas Sep 12 '16 at 07:32
  • 2
    @Thomas yeah it has always been m not M, so it definitely is megabyte, because I ran a test myself. – CppLearner Sep 12 '16 at 18:45
  • 1
    Thank you both - i've deleted the bit/byte bit. – J.J Aug 14 '17 at 17:20
  • 3
    As of 2018 and nginx version 1.14.1, this seems fixed — `client_max_body_size` is honored in section `http` without needing to add it anywhere else. – DomQ Nov 20 '18 at 17:30
34

You need to apply following changes:

  1. Update php.ini (Find right ini file from phpinfo();) and increase post_max_size and upload_max_filesize to size you want:

    sed -i "s/post_max_size =.*/post_max_size = 200M/g" /etc/php5/fpm/php.ini
    sed -i "s/upload_max_filesize =.*/upload_max_filesize = 200M/g" /etc/php5/fpm/php.ini```
    
  2. Update NginX settings for your website and add client_max_body_size value in your location, http, or server context.

    location / {
        client_max_body_size 200m;
        ...
    }
    
  3. Restart NginX and PHP-FPM:

    service nginx restart
    service php5-fpm restart
    

NOTE: Sometime (In my case almost every time) you need to kill php-fpm process if it didn't refresh by service command properly. To do that you can get list of processes (ps -elf | grep php-fpm) and kill one by one (kill -9 12345) or use following command to do it for you:

ps -elf | grep php-fpm | grep -v grep | awk '{ print $4 }' | xargs kill -9
Qorbani
  • 5,825
  • 2
  • 39
  • 47
15

Please see if you are setting client_max_body_size directive inside http {} block and not inside location {} block. I have set it inside http{} block and it works

rjha94
  • 4,292
  • 3
  • 30
  • 37
  • yes, confirmed, all it needs is the directive in the http block, not the location or the server blocks. – steev Aug 18 '23 at 19:36
14

Someone correct me if this is bad, but I like to lock everything down as much as possible, and if you've only got one target for uploads (as it usually the case), then just target your changes to that one file. This works for me on the Ubuntu nginx-extras mainline 1.7+ package:

location = /upload.php {
    client_max_body_size 102M;
    fastcgi_param PHP_VALUE "upload_max_filesize=102M \n post_max_size=102M";
    (...)
}
digitaltoast
  • 659
  • 7
  • 23
  • I like this idea too however for me it it does not work this way. All I can do is reduce the the value and not increase it at location level. – Geza Turi Dec 05 '16 at 03:53
8

I had a similar problem recently and found out, that client_max_body_size 0; can solve such an issue. This will set client_max_body_size to no limit. But the best practice is to improve your code, so there is no need to increase this limit.

Adrián Molčan
  • 133
  • 1
  • 6
5

I meet the same problem, but I found it nothing to do with nginx. I am using nodejs as backend server, use nginx as a reverse proxy, 413 code is triggered by node server. node use koa parse the body. koa limit the urlencoded length.

formLimit: limit of the urlencoded body. If the body ends up being larger than this limit, a 413 error code is returned. Default is 56kb.

set formLimit to bigger can solve this problem.

pangpang
  • 8,581
  • 11
  • 60
  • 96
4

Assuming you have already set the client_max_body_size and various PHP settings (upload_max_filesize / post_max_size , etc) in the other answers, then restarted or reloaded NGINX and PHP without any result, run this...

nginx -T

This will give you any unresolved errors in your NGINX configs. In my case, I struggled with the 413 error for a whole day before I realized there were some other unresolved SSL errors in the NGINX config (wrong pathing for certs) that needed to be corrected. Once I fixed the unresolved issues I got from 'nginx -T', reloaded NGINX, and EUREKA!! That fixed it.

P-Didz
  • 51
  • 2
4

In case you are using Kubernetes, add the following annotations to your Ingress:

annotations:
  nginx.ingress.kubernetes.io/client-max-body-size: "5m"
  nginx.ingress.kubernetes.io/client-body-buffer-size: "8k"
  nginx.ingress.kubernetes.io/proxy-body-size: "5m"
  nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"

Confirm the changes were applied:

kubectl -n <namespace> describe ingress <ingress-name>

References:

Esteban Gatjens
  • 4,651
  • 1
  • 14
  • 8
3

I'm setting up a dev server to play with that mirrors our outdated live one, I used The Perfect Server - Ubuntu 14.04 (nginx, BIND, MySQL, PHP, Postfix, Dovecot and ISPConfig 3)

After experiencing the same issue, I came across this post and nothing was working. I changed the value in every recommended file (nginx.conf, ispconfig.vhost, /sites-available/default, etc.)

Finally, changing client_max_body_size in my /etc/nginx/sites-available/apps.vhost and restarting nginx is what did the trick. Hopefully it helps someone else.

Jeramiah Harland
  • 854
  • 7
  • 15
2

Warning for Cloudflare

Posting this as a warning for other Cloudflare users because I went through the Nginx docs and all the other answers here thoroughly before I finally figured out the issue.

Cloudflare free and Pro plans limit you to 100MB file upload size (reference).

So if the file size is over 100MB Cloudflare will return a 413 response and the request won't ever hit your server.

The solutions suggested are to either use a subdomain that is not proxied through Cloudflare for your upload endpoint or break the file up into chunks that are smaller than 100MB.

Hope this saves someone else some time!

AdamPal
  • 61
  • 5
0

Had the same issue that the client_max_body_size directive was ignored.

My silly error was, that I put a file inside /etc/nginx/conf.d which did not end with .conf. Nginx will not load these by default.

Philippe Gerber
  • 17,457
  • 6
  • 45
  • 40
0

If you are using windows version nginx, you can try to kill all nginx process and restart it to see. I encountered same issue In my environment, but resolved it with this solution.

nathan.xu
  • 201
  • 4
  • 7
  • 2
    That was my issue, thank you! One Nginx instance was not exited properly I guess. It is never bad to check if it is exited on windows ```tasklist /fi "imagename eq nginx.exe"``` – Valery Baranov Dec 24 '18 at 20:57
0

If you tried the above options and no success, also you're using IIS (iisnode) to host your node app, putting this code on web.config resolved the problem for me:

Here is the reference: https://www.inflectra.com/support/knowledgebase/kb306.aspx

Also, you can chagne the length allowed because now I think its 2GB. Modify it by your needs.

  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="2147483648" />
    </requestFiltering>
  </security>
developer_009
  • 317
  • 3
  • 11
0

The following config worked for me. Notice I only set client_max_body_size 50M; once, contrary to what others are saying...

File: /etc/nginx/conf.d/sites.conf

server {
    listen 80 default_server;
    server_name portal.myserver.com;
    return 301 https://$host$request_uri;
}

server {
    resolver 127.0.0.11 valid=30s;
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    ssl_certificate /secret/portal.myserver.com.crt;
    ssl_certificate_key /secret/portal.myserver.com.pem;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    server_name portal.myserver.com;
    client_max_body_size 50M;
    location /fileserver/ {
        set $upstream http://fileserver:6976;
        proxy_pass $upstream;
    }
}

birgersp
  • 3,909
  • 8
  • 39
  • 79