272

I am getting these kind of errors:

2014/05/24 11:49:06 [error] 8376#0: *54031 upstream sent too big header while reading response header from upstream, client: 107.21.193.210, server: aamjanata.com, request: "GET /the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https://aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20ht

Always it is the same. A url repeated over and over with comma separating. Can't figure out what is causing this. Anyone have an idea?

Update: Another error:

http request count is zero while sending response to client

Here is the config. There are other irrelevant things, but this part was added/edited

fastcgi_cache_path /var/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
proxy_buffer_size   128k;
proxy_buffers   4 256k;
proxy_busy_buffers_size   256k;
    # Upstream to abstract backend connection(s) for PHP.
    upstream php {
            #this should match value of "listen" directive in php-fpm pool
            server unix:/var/run/php5-fpm.sock;
    }

And then in the server block: set $skip_cache 0;

    # POST requests and urls with a query string should always go to PHP
    if ($request_method = POST) {
            set $skip_cache 1;
    }
    if ($query_string != "") {
            set $skip_cache 1;
    }

    # Don't cache uris containing the following segments
    if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
            set $skip_cache 1;
    }

    # Don't use the cache for logged in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
            set $skip_cache 1;
    }

    location / {
            # This is cool because no php is touched for static content.
            # include the "?$args" part so non-default permalinks doesn't break when using query string
            try_files $uri $uri/ /index.php?$args;
    }


    location ~ \.php$ {
            try_files $uri /index.php;
            include fastcgi_params;
            fastcgi_pass php;
            fastcgi_read_timeout 3000;

            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;

            fastcgi_cache WORDPRESS;
            fastcgi_cache_valid  60m;
    }

    location ~ /purge(/.*) {
        fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
    }`
Paulo Boaventura
  • 1,032
  • 1
  • 7
  • 25
Vidyut
  • 2,881
  • 2
  • 10
  • 9
  • your proxy config does not seem right. Can you share the config? – Neo May 24 '14 at 12:06
  • can you try adding: fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; – Neo May 24 '14 at 13:07
  • 2
    possible duplicate of [Upstream too big - nginx + codeigniter](http://stackoverflow.com/questions/13894386/upstream-too-big-nginx-codeigniter) – dnozay Mar 18 '15 at 19:17

10 Answers10

475

Add the following to your conf file

fastcgi_buffers 16 16k; 
fastcgi_buffer_size 32k;
Neo
  • 5,639
  • 1
  • 17
  • 25
  • 172
    While your answer led me to the correct response, you should show how to determine the correct buffer sizes and why that matters. Otherwise it's a shot in the dark. See here for getting an idea on sizing: https://gist.github.com/magnetikonline/11312172#determine-fastcgi-response-sizes – Wes Johnson Sep 09 '14 at 15:37
  • 1
    I'm under the impression that only the second parameter actually matters, because it is about "the first part of the response" which "usually contains a small response header", see http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffer_size – greg0ire Aug 05 '15 at 12:47
  • @greg0ire you mean just fastcgi_buffer_size 32k; ? That is right. For the issue with response headers, just the fastcgi_buffer_size param should do. The fastcgi_buffers help in the total size of the buffer. It helps in solving the issues when "upstream response is buffered to a temporary file" is seen. – Neo Aug 05 '15 at 16:59
  • 6
    "fastcgi_buffer_size 32k;" alone did not work, I needed both lines for NginX to restart. I came here because of a 502 error with NginX caused by a WordPress plugin. – PJ Brunet Apr 19 '16 at 21:20
  • 7
    If `fast_cgi_buffers` don't help, try the `proxy_buffers` [answer below](http://stackoverflow.com/a/27551259/327074) by @amd – icc97 Mar 29 '17 at 12:13
  • 17
    Any explanation on this answer please. – Edson Horacio Junior May 17 '17 at 18:28
  • It seems like nginx is 502ing when part of the header is split across buffer chunks. Raising the buffer size reduces (but doesn't eliminate) the chance of this happening. Here's some more detail: https://gist.github.com/neerolyte/752f915736d133f170fc62a04f642de0 – lyte Aug 08 '17 at 23:08
  • 1
    I actually think the correct answer to this should be to fix php-fpm config so that errors are written to the php-fpm error.log, instead of stderr. – lyte Aug 08 '17 at 23:10
  • 9
    Its works for me, I just want to add that in ubuntu 16.04 the nginx configuration file is located at `/etc/nginx/nginx.conf` and the values should go inside http {...} – Mario Feb 26 '18 at 17:20
  • I also raised the buffer size. But I'm at the point that I want to know what plugin caused the Reponse header to be that big that the 502 error occured. Any tips on how to find the cause of the problem? In my case it was only happening on a certain WP page while being logged in. – Bas van Dijk Apr 11 '18 at 09:18
  • My nginx.conf had `gzip_buffers 16 8k` by default, so setting `fastcgi_buffer_size 32k` alone failed as it exceeded the 8k buffer size. Seems you can *either* set *both* options, *or* reduce the `fastcgi_buffer_size` option to match `gzip_buffers`. Not sure on exact requirements: YMMV – Dave S Jun 18 '18 at 13:29
  • 1
    You can find the information on how to tune `fastcgi_buffer_size` [here](https://www.getpagespeed.com/server-setup/nginx/tuning-proxy_buffer_size-in-nginx) – Danila Vershinin Jul 08 '18 at 07:14
  • You saved me a lot of time bro, Thanks. – Yassine Mokni Nov 02 '19 at 21:52
  • Works for me! Would `fastcgi_buffers 32 32k` be even faster? Or should you keep the buffer segment count low? as in `fastcgi_buffers 16 32k`? – Justin Breen Jan 05 '20 at 17:41
  • This might help some: https://ma.ttias.be/nginx-proxy-upstream-sent-big-header-reading-response-header-upstream/ – spekulatius Nov 04 '20 at 13:48
166

If nginx is running as a proxy / reverse proxy

that is, for users of ngx_http_proxy_module

In addition to fastcgi, the proxy module also saves the request header in a temporary buffer.

So you may need also to increase the proxy_buffer_size and the proxy_buffers, or disable it totally (Please read the nginx documentation).

Example of proxy buffering configuration

http {
  proxy_buffer_size   128k;
  proxy_buffers   4 256k;
  proxy_busy_buffers_size   256k;
}

Example of disabling your proxy buffer (recommended for long polling servers)

http {
  proxy_buffering off;
}

For more information: Nginx proxy module documentation

icc97
  • 8,746
  • 6
  • 60
  • 75
amd
  • 18,048
  • 6
  • 45
  • 64
  • 8
    "proxy_busy_buffers_size" must be less than the size of all "proxy_buffers" minus one buffer – chovy Mar 30 '15 at 04:30
  • you are the man! thanks! first option worked in my ruby on rails app – Nezir May 27 '19 at 16:38
  • Probably a silly question, but I have a proxy in front of the server that is returning this error. Changing the buffer worked, but I get a new error on the inside machine. `writev() failed (104: Connection reset by peer) while sending to client` Would those proxy settings possibly fix that error, and would hey go on the upstream server or the proxy? – Adam Patterson Aug 15 '19 at 02:35
  • 2
    Why the `proxy_buffers 4 ...` ? Since default seems to be 8 – adrianTNT Jan 30 '20 at 02:47
  • See also: https://www.getpagespeed.com/server-setup/nginx/tuning-proxy_buffer_size-in-nginx – Eugen Mihailescu Jul 08 '20 at 07:23
  • For me, setting buffers was still necessary despite setting buffering off... – Luc Dec 06 '20 at 18:57
31

Plesk instructions

I combined the top two answers here

In Plesk 12, I had nginx running as a reverse proxy (which I think is the default). So the current top answer doesn't work as nginx is also being run as a proxy.

I went to Subscriptions | [subscription domain] | Websites & Domains (tab) | [Virtual Host domain] | Web Server Settings.

Then at the bottom of that page you can set the Additional nginx directives which I set to be a combination of the top two answers here:

fastcgi_buffers         16  16k;
fastcgi_buffer_size         32k;
proxy_buffer_size          128k;
proxy_buffers            4 256k;
proxy_busy_buffers_size    256k;
icc97
  • 8,746
  • 6
  • 60
  • 75
  • 1
    Where? Which config? – Redsandro Nov 13 '17 at 11:12
  • @Redsandro If you can't find it via `Subscriptions | [subscription domain] | Websites & Domains (tab) | [Virtual Host domain] | Web Server Settings` then I'm not sure what you mean? – icc97 Nov 13 '17 at 12:00
  • 1
    this was the solution for me: Domains > Domain name > Apache & nginx Settings > Additional nginx directives Plesk Onyx Version 17.8.11 – dijkstra8x Feb 26 '19 at 16:07
  • 1
    I added this in a new file `/etc/nginx/conf.d/proxy.conf` and restarted nginx, it works fine, thanks! – rubo77 Jul 10 '19 at 12:40
26

upstream sent too big header while reading response header from upstream is nginx's generic way of saying "I don't like what I'm seeing"

  1. Your upstream server thread crashed
  2. The upstream server sent an invalid header back
  3. The Notice/Warnings sent back from STDERR overflowed their buffer and both it and STDOUT were closed

3: Look at the error logs above the message, is it streaming with logged lines preceding the message? PHP message: PHP Notice: Undefined index: Example snippet from a loop my log file:

2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
... // 20 lines of same
PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undef
2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "ta_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Firstname

you can see in the 3rd line from the bottom that the buffer limit was hit, broke, and the next thread wrote in over it. Nginx then closed the connection and returned 502 to the client.

2: log all the headers sent per request, review them and make sure they conform to standards (nginx does not permit anything older than 24 hours to delete/expire a cookie, sending invalid content length because error messages were buffered before the content counted...). getallheaders function call can usually help out in abstracted code situations php get all headers

examples include:

<?php
//expire cookie
setcookie ( 'bookmark', '', strtotime('2012-01-01 00:00:00') );
// nginx will refuse this header response, too far past to accept
....
?>

and this:

<?php
header('Content-type: image/jpg');
?>

<?php   //a space was injected into the output above this line
header('Content-length: ' . filesize('image.jpg') );
echo file_get_contents('image.jpg');
// error! the response is now 1-byte longer than header!!
?>

1: verify, or make a script log, to ensure your thread is reaching the correct end point and not exiting before completion.

ppostma1
  • 3,278
  • 1
  • 24
  • 27
  • 4
    This answer hit the nail in the head. Sometimes it's not just the configuration of nginx, but what's actually producing the header. When error_reporting contains the notices but display_errors is off in php.ini, all the messages show up in FCGI header instead of content. – Schien Apr 23 '18 at 20:49
6

If you're using Symfony framework: Before messing with Nginx config, try to disable ChromePHP first.

1 - Open app/config/config_dev.yml

2 - Comment these lines:

#chromephp:
    #type:   chromephp
    #level:  info

ChromePHP pack the debug info json-encoded in the X-ChromePhp-Data header, which is too big for the default config of nginx with fastcgi.

Source: https://github.com/symfony/symfony/issues/8413#issuecomment-20412848

Lucas Bustamante
  • 11,643
  • 6
  • 66
  • 74
5

We ended up realising that our one server that was experiencing this had busted fpm config resulting in php errors/warnings/notices that'd normally be logged to disk were being sent over the FCGI socket. It looks like there's a parsing bug when part of the header gets split across the buffer chunks.

So setting php_admin_value[error_log] to something actually writeable and restarting php-fpm was enough to fix the problem.

We could reproduce the problem with a smaller script:

<?php
for ($i = 0; $i<$_GET['iterations']; $i++)
    error_log(str_pad("a", $_GET['size'], "a"));
echo "got here\n";

Raising the buffers made the 502s harder to hit but not impossible, e.g native:

bash-4.1# for it in {30..200..3}; do for size in {100..250..3}; do echo "size=$size iterations=$it $(curl -sv "http://localhost/debug.php?size=$size&iterations=$it" 2>&1 | egrep '^< HTTP')"; done; done | grep 502 | head
size=121 iterations=30 < HTTP/1.1 502 Bad Gateway
size=109 iterations=33 < HTTP/1.1 502 Bad Gateway
size=232 iterations=33 < HTTP/1.1 502 Bad Gateway
size=241 iterations=48 < HTTP/1.1 502 Bad Gateway
size=145 iterations=51 < HTTP/1.1 502 Bad Gateway
size=226 iterations=51 < HTTP/1.1 502 Bad Gateway
size=190 iterations=60 < HTTP/1.1 502 Bad Gateway
size=115 iterations=63 < HTTP/1.1 502 Bad Gateway
size=109 iterations=66 < HTTP/1.1 502 Bad Gateway
size=163 iterations=69 < HTTP/1.1 502 Bad Gateway
[... there would be more here, but I piped through head ...]

fastcgi_buffers 16 16k; fastcgi_buffer_size 32k;:

bash-4.1# for it in {30..200..3}; do for size in {100..250..3}; do echo "size=$size iterations=$it $(curl -sv "http://localhost/debug.php?size=$size&iterations=$it" 2>&1 | egrep '^< HTTP')"; done; done | grep 502 | head
size=223 iterations=69 < HTTP/1.1 502 Bad Gateway
size=184 iterations=165 < HTTP/1.1 502 Bad Gateway
size=151 iterations=198 < HTTP/1.1 502 Bad Gateway

So I believe the correct answer is: fix your fpm config so it logs errors to disk.

lyte
  • 1,007
  • 10
  • 9
3

Add:

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
proxy_buffer_size   128k;
proxy_buffers   4 256k;
proxy_busy_buffers_size   256k;

To server{} in nginx.conf

Works for me.

2

This is still the highest SO-question on Google when searching for this error, so let's bump it.

When getting this error and not wanting to deep-dive into the NGINX settings immediately, you might want to check your outputs to the debug console. In my case I was outputting loads of text to the FirePHP / Chromelogger console, and since this is all sent as a header, it was causing the overflow.

It might not be needed to change the webserver settings if this error is caused by just sending insane amounts of log messages.

DavidKunz
  • 199
  • 2
  • 7
2

I am not sure that the issue is related to what header php is sending. Make sure that the buffering is enabled. The simple way is to create a proxy.conf file:

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    100m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffering         on;
proxy_buffer_size       128k;
proxy_buffers           4 256k;
proxy_busy_buffers_size 256k;

And a fascgi.conf file:

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;
fastcgi_buffers 128 4096k;
fastcgi_buffer_size 4096k;
fastcgi_index  index.php;
fastcgi_param  REDIRECT_STATUS    200;

Next you need to call them in your default config server this way:

http {
  include    /etc/nginx/mime.types;
  include    /etc/nginx/proxy.conf;
  include    /etc/nginx/fastcgi.conf;
  index    index.html index.htm index.php;
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
    '"$request" $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
  #access_log   /logs/access.log  main;
  sendfile     on;
  tcp_nopush   on;
 # ........
}
macherif
  • 348
  • 2
  • 5
0

In our case we got this nginx error because our backend generated redirect response with a very long URL:

HTTP/1.1 301 Moved Permanently 
Location: https://www.example.com/?manyParamsHere...

Just for curiosity, we saved that big URL to a file and it size was 4.4 Kb.

Adding two lines to the config file /etc/nginx/conf.d/some_site.conf helped us to fix this error:

server {
    # ...
    location ~ ^/index\.php(/|$) {
        fastcgi_pass php-upstream;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Add these lines:
        fastcgi_buffer_size 32k;
        fastcgi_buffers 4 32k;
    }
}

Read more about these params at the official nginx documentation.

yesnik
  • 2,425
  • 23
  • 20