DEV Community

Cover image for Warning in the nginx log, need explanation of the request
Faizan
Faizan

Posted on Originally published at headsntail.com

Warning in the nginx log, need explanation of the request

The most common mistake with this warning is treating it as an error and raising every buffer in nginx.conf until it disappears. It isn't an error. The request worked, and nginx is just telling you it used the disk. If you searched "warning in the nginx log, need explanation of the request", this walks through reading the line, finding what caused it, and fixing it only where it matters.

A [warn] line saying a request body or upstream response "is buffered to a temporary file" means the data was bigger than nginx's memory buffers, so nginx wrote it to disk. The request still succeeded. The request: field shows which URL caused it. Raise client_body_buffer_size or fastcgi_buffers for that location only if it happens often.

What the nginx "buffered to a temporary file" warning means

Running example: a Laravel admin panel on a VPS, nginx in front of PHP-FPM. The error log shows two kinds of lines:

2026/10/20 09:14:02 [warn] 2154#2154: *8812 a client request body is buffered to a temporary file /var/lib/nginx/body/0000000007, client: 203.0.113.50, server: example.com, request: "POST /admin/uploads HTTP/1.1", host: "example.com"
Enter fullscreen mode Exit fullscreen mode
2026/10/20 09:15:40 [warn] 2154#2154: *8840 an upstream response is buffered to a temporary file /var/lib/nginx/fastcgi/2/00/0000000002 while reading upstream, client: 203.0.113.50, server: example.com, request: "GET /reports/download HTTP/1.1", upstream: "fastcgi://unix:/run/php/php-fpm.sock:", host: "example.com"
Enter fullscreen mode Exit fullscreen mode

The first is about data coming in (an upload). The second is about data going out (PHP's response). Both say the same thing: it didn't fit in memory, so nginx spooled it to a file and carried on.

Warning in the nginx log, need explanation of the request? Fix it in 6 steps

Step 1: Pull the warnings and split the fields

sudo grep '\[warn\]' /var/log/nginx/error.log | tail -n 20
Enter fullscreen mode Exit fullscreen mode

Every line follows the same layout:

  • 2026/10/20 09:14:02 is the time, [warn] is the level.
  • 2154#2154 is the worker PID and thread ID. You can ignore it.
  • *8812 is the connection ID. Use it to find other lines from the same connection.
  • client: is the IP that sent the request. If it's always your load balancer or Cloudflare, the X-Real-IP fix for nginx gets you the real visitor address.
  • request: is the method, URL and protocol. This is the part you actually care about.
  • upstream: is the backend nginx was talking to. If that term's new, here's what upstream means in nginx.

Step 2: Count which URLs trigger it

One warning a week is noise. Hundreds on one URL is worth a look:

sudo grep 'buffered to a temporary file' /var/log/nginx/error.log \
  | grep -o 'request: "[^"]*"' | sort | uniq -c | sort -rn | head
Enter fullscreen mode Exit fullscreen mode

In the running example you'd see POST /admin/uploads and GET /reports/download at the top. Both make sense: uploads are big requests, downloads are big responses.

Step 3: Check your current buffer sizes

Dump the full loaded config and look for the relevant directives:

sudo nginx -T 2>/dev/null | grep -E 'client_body_buffer_size|fastcgi_buffers|fastcgi_buffer_size|fastcgi_max_temp_file_size'
Enter fullscreen mode Exit fullscreen mode

If nothing prints, you're on nginx's defaults, which are small: a couple of memory pages for the request body and a handful of small buffers for the FastCGI response. Measure what you're actually sending:

curl -s -o /dev/null -w '%{size_download}\n' -H 'Cookie: laravel_session=YOUR_SESSION' https://example.com/reports/download
Enter fullscreen mode Exit fullscreen mode

If that prints several megabytes, no reasonable memory buffer will hold it, and that's fine.

Step 4: Fix the request body warning for uploads only

For the upload route, raise the body buffer in that location only:

location = /admin/uploads {
    client_max_body_size 20m;
    client_body_buffer_size 1m;

    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
    fastcgi_pass unix:/run/php/php-fpm.sock;
}
Enter fullscreen mode Exit fullscreen mode

Don't copy client_body_buffer_size up to the same value as client_max_body_size, and don't set it in the http block. It's memory reserved per request, so a large global value means every concurrent upload can grab that much RAM. Files bigger than the buffer will still go to disk, and that's the correct behaviour.

Step 5: Fix the upstream response warning for downloads

For normal pages, slightly bigger FastCGI buffers usually stop the warning:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php/php-fpm.sock;
    fastcgi_buffer_size 16k;
    fastcgi_buffers 16 16k;
}
Enter fullscreen mode Exit fullscreen mode

For real file downloads, I'd stop sending the file through PHP at all. Let nginx serve it with X-Accel-Redirect:

location /protected-exports/ {
    internal;
    alias /var/www/app/storage/app/exports/;
}
Enter fullscreen mode Exit fullscreen mode
return response('', 200, [
    'Content-Type'        => 'text/csv',
    'Content-Disposition' => 'attachment; filename="report.csv"',
    'X-Accel-Redirect'    => '/protected-exports/report.csv',
]);
Enter fullscreen mode Exit fullscreen mode

Laravel still checks auth, but nginx streams the file from disk, and the PHP worker is free immediately. The internal line stops anyone requesting /protected-exports/ directly.

What I'd skip: fastcgi_max_temp_file_size 0;. It removes the warning, but then a slow client holds the PHP-FPM worker until the whole response is sent, which is worse than a temp file. Same for setting error_log ... error; to hide warnings. You'll hide the next warning that does matter.

Step 6: Check the temp directory if uploads fail

There's a nastier cousin of this warning. If nginx can't write the temp file, it logs a [crit] line and the request fails with a 500:

[crit] 2154#2154: *8901 open() "/var/lib/nginx/body/0000000011" failed (13: Permission denied), client: 203.0.113.50, server: example.com, request: "POST /admin/uploads HTTP/1.1", host: "example.com"
Enter fullscreen mode Exit fullscreen mode

This usually happens after changing the user directive in nginx.conf. Fix the ownership to match your nginx user (www-data on Debian and Ubuntu):

sudo chown -R www-data:www-data /var/lib/nginx
Enter fullscreen mode Exit fullscreen mode

Paths differ by distro. RHEL-based systems keep these under /var/lib/nginx/tmp/. The open() path in the log tells you exactly where to look.

Verify the warning is gone for that request

Reload and repeat the same request:

sudo nginx -t && sudo systemctl reload nginx
sudo tail -f /var/log/nginx/error.log | grep --line-buffered 'buffered to a temporary file'
Enter fullscreen mode Exit fullscreen mode

Upload a file of the size your users normally send, then download the report. Small and medium requests should no longer produce a line. Very large uploads will still log the warning, and that's expected. If you want to see how long those requests take, the timing log format in the nginx 499 guide adds $request_time to your access log.

Next steps

Leave nginx's other defaults alone unless a log line points at them. If you're seeing [crit] or [error] lines alongside these warnings and can't place them, contact HeadsNTail with a few sample lines.

FAQ

Is "a client request body is buffered to a temporary file" an error?

No. It's a [warn] level message and the request completes normally. It only means the upload was bigger than client_body_buffer_size, so nginx stored it on disk first.

Where does nginx store temporary files?

In the paths set by client_body_temp_path, fastcgi_temp_path and proxy_temp_path. On Debian and Ubuntu these default to subfolders of /var/lib/nginx/. The exact path appears in the warning itself.

What's the difference between this warning and "upstream sent too big header"?

"Buffered to a temporary file" is about the response body and is harmless. "Upstream sent too big header while reading response header from upstream" is an [error] that returns a 502, usually from large cookies or headers. Raise fastcgi_buffer_size (or proxy_buffer_size) to fix that one.

Does the same warning appear with proxy_pass?

Yes, with a /var/lib/nginx/proxy/ path instead. The fixes are the proxy versions of the same directives: proxy_buffer_size, proxy_buffers and X-Accel-Redirect for downloads.

Next time you see a warning in the nginx log, need explanation of the request, start with the request: field and Step 2's count before touching any buffer.


Originally published at headsntail.com. Free tools for PHP, Laravel and cPanel work: headsntail.com/tools.

Top comments (0)