Nginx break in latest version

Hello,

After this upgrade of NGINX


[14:24:05] [root@server ~]# dnf history info nginx
Transaction ID : 558
Begin time     : Fri Sep 11 12:42:46 2026
Begin rpmdb    : 7853db1b7440a37bcbe8fca1ff0aae7daf43003234275a3910b5968997121f89 **
End time       : Fri Sep 11 12:43:07 2026 (21 seconds)
End rpmdb      : cf09e6362ea516fdac0dd602e7ba8523f9120f4e2ff8cc0bc0d664f589864566
User           : System <unset>
Return-Code    : Success
Releasever     : 9
Command Line   : -y --best --allowerasing install nginx
Persistence    : Persist
Comment        : 
Packages Altered:
    Upgrade  nginx-2:1.20.1-28.el9_8.6.rocky.0.1.x86_64            @appstream
    Upgraded nginx-2:1.20.1-28.el9_8.5.rocky.0.1.x86_64            @@System
    Upgrade  nginx-core-2:1.20.1-28.el9_8.6.rocky.0.1.x86_64       @appstream
    Upgraded nginx-core-2:1.20.1-28.el9_8.5.rocky.0.1.x86_64       @@System
    Upgrade  nginx-filesystem-2:1.20.1-28.el9_8.6.rocky.0.1.noarch @appstream
    Upgraded nginx-filesystem-2:1.20.1-28.el9_8.5.rocky.0.1.noarch @@System

i have this in logs:

8060#8060: *45 no buffer space in script copy

The installation contains a simple nginx + fcgi proxy to a php fpm instance.

After rolling back to previous version, it’s fixed.

For those who don’t know how to rollback.

dnf history info nginx

Retrieve the transaction number then

dnf history undo <TRANSACTION_ID>
systemctl restart nginx

From a quick google search it suggests that fixes to Nginx for CVE’s are what cause those errors to be logged. That would mean that perhaps something is wrong with your nginx configuration and you need to update it to get it working again.

Hello,

Thanks @iwalker for your “very nice” answer.

What are the changed present in this upgrade ? i didn’t got theses error previously.

I will not respond about the “quick search google” which return me Bug #2164558 “nginx 1.24.0-2ubuntu7.16 regression: “no buffer sp...” : Bugs : nginx package : Ubuntu . It could be related because it’s not old, but i discard. it since it’s not the same version nor distribution.

I would reconsider my version if there were a change in the ngixn version, but that’s not the case, the only chance should concern the way of how it’s packaged.

PS: i didn’t precise, but php fpm is totally unreacheable whereas it worked before.

We found some servers with sames versions which seems to still works, we investigate.

If you could post your nginx configuration, we could perhaps help more. There are also the nginx modules available on Rocky 9, so you can try even a newer version of nginx instead of the base one. As the base is 1.20, with the modules you can also use 1.22, 1.24 and 1.26.

It is possible a regression has been added to the package that causes this and not necessarily the config of nginx. If you have upgraded other servers and they are working with php-fpm, then it would make sense to check the configuration of the other one to find out why it’s not working.

I can confirm the issue reported by @henri9813 and provide some additional investigation below with strace evidence.


Summary

After updating to nginx 2:1.20.1-28.el9_8.6.rocky.0.1, all PHP-FPM requests fail with HTTP 500 when SCRIPT_FILENAME uses $realpath_root and the document root goes through a symlink. This worked perfectly on the previous build (-el9_8.5).

The error log shows this alert on every request:

[alert] no buffer space in script copy

Environment

Component Detail
OS Rocky Linux 9.8
Stack nginx → php-fpm 8.3 via Unix socket
Docroot layout Capistrano-style symlink: /var/www/<app>/htdocs/current → /var/www/<app>/htdocs/releases/<ts> nginx root points to /var/www/<app>/htdocs/releases/<ts>/current/pub

Package versions

working : 2:1.20.1-28.el9_8.5.rocky.0.1
broken  : 2:1.20.1-28.el9_8.6.rocky.0.1

nginx configuration (simplified)

server {
    server_name example.com;
    root /var/www/<app>/htdocs/current/pub;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/run/php-fpm/<app>.sock;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

How to reproduce

  1. Rocky 9.8 with nginx 2:1.20.1-28.el9_8.6.rocky.0.1
  2. Any PHP app behind php-fpm, docroot reached through a symlink (current → releases/<ts>), $realpath_root used in SCRIPT_FILENAME
  3. Run:
    curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: example.com' http://127.0.0.1/health_check.php
    

Actual result: HTTP 500 (nginx’s own default error page). Error log:

[alert] <pid>#<tid>: *2003 no buffer space in script copy, client: 127.0.0.1, server: example.com, request: "GET /health_check.php HTTP/1.1", host: "127.0.0.1"

Expected result: HTTP 200. The identical config worked on the same host with el9_8.5 until the package update; the alerts started immediately after.


Impact

  • 100 % of PHP requests fail the application is completely down
  • php-fpm itself is healthy; the failure happens entirely inside the nginx worker

Root cause analysis (strace of the nginx worker)

Failing case $realpath_root on el9_8.6

Key observation: nginx never connects to the FPM socket. The 500 is generated internally before the FastCGI request is even sent.

recvfrom(3, "GET /health_check.php HTTP/1.1\r\n"..., 1024, 0, NULL, NULL) = 70
newfstatat(AT_FDCWD, "/var/www/<app>/htdocs/current/pub/health_check.php", {st_mode=S_IFREG|0665, st_size=3481, ...}, 0) = 0
readlink("/var", 0x7fffec862410, 1023)                                = -1 EINVAL
readlink("/var/www", 0x7fffec862410, 1023)                            = -1 EINVAL
readlink("/var/www/<app>", 0x7fffec862410, 1023)                      = -1 EINVAL
readlink("/var/www/<app>/htdocs", 0x7fffec862410, 1023)               = -1 EINVAL
readlink("/var/www/<app>/htdocs/current", "/var/www/<app>/htdocs/releases/<ts>"..., 1023) = 64
readlink("/var/www/<app>/htdocs/releases", 0x7fffec862410, 1023)      = -1 EINVAL
readlink("/var/www/<app>/htdocs/releases/<ts>", 0x7fffec862410, 1023) = -1 EINVAL
... (the full readlink() chain is repeated a second time)
write(27, "... [alert] ... no buffer space in script copy ...", 198)  = 198
writev(3, [..., "HTTP/1.1 500 Internal Server Error"..., "<hr><center>nginx</center>"...], 3) = 413
close(3)

Working case, same request with $document_root

Zero readlink() calls, normal FastCGI exchange:

recvfrom(4, "GET /health_check.php HTTP/1.1\r\n"..., 1024, 0, NULL, NULL) = 70
newfstatat(AT_FDCWD, "/var/www/<app>/htdocs/current/pub/health_check.php", {...}, 0) = 0
socket(AF_UNIX, SOCK_STREAM, 0) = 6
connect(6, {sa_family=AF_UNIX, sun_path="/run/php-fpm/<app>.sock"}, 110) = 0
writev(6, [{iov_base="\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0\1\4\0\1\2\343\5\0\0104PHP_FL"..., iov_len=784}], 1) = 784
recvfrom(6, "\1\6\0\1\0*\6\0Content-type: text/html;"..., 32768, 0, NULL, NULL) = 72
readv(6, [{iov_base="", iov_len=32696}], 1) = 0
writev(4, [{iov_base="HTTP/1.1 200 OK\r\nServer: nginx\r\n"..., iov_len=254}, {iov_base="0\r\n\r\n", iov_len=5}], 2) = 259
close(4)

Interpretation

The strace output makes the root cause clear:

  1. $realpath_root triggers symlink resolution. The readlink() syscalls visible in the failing trace are the kernel resolving each path component of the docroot that is how $realpath_root works under the hood: it walks the path and resolves every symlink to produce the final absolute path. On the working trace ($document_root), there are zero readlink() calls because $document_root simply uses the configured path string as-is.

  2. The resolved path breaks nginx’s internal buffer. Once the symlink is resolved, the resulting SCRIPT_FILENAME value (e.g. /var/www/<app>/htdocs/releases/<ts>/pub/health_check.php) is longer than the original symlinked path. The el9_8.6 rebuild apparently changed how nginx sizes or handles that internal buffer leading to the “no buffer space in script copy” alert. The request never reaches php-fpm (no connect() to the FPM socket in the trace); nginx fails internally before it can even build the FastCGI request.

  3. The symlink is stable. Verified with readlink -f, namei -l, and inotifywait -m on the parent directory no modification, no redeployment happening during the failures.

  4. php-fpm is healthy. Pool up, socket valid, no FPM or kernel errors. Restarting php-fpm does not fix the issue confirming the problem is entirely on the nginx side.


Workaround

Replace $realpath_root with $document_root in the SCRIPT_FILENAME parameter:

# Before (broken)
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

# After (works)
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

$document_root passes the configured path as-is without resolving symlinks, which avoids the bug entirely.