SSD Nodes Learn Hosting plans →
Guides Matt ConnorBy Matt Connor

nginx: no buffer space in script copy

Random HTTP 500s after an nginx security update? Find the volatile map behind this alert and install AlmaLinux's fixed build without losing the CVE patch.

What does no buffer space in script copy mean?

The nginx error no buffer space in script copy means a bounds check failed while nginx was building a string, so nginx answered that request with HTTP 500. On AlmaLinux, this check can fail on a healthy config after the CVE-2026-42533 update, because the backported fix keeps one buffer end in a global variable and nested script runs overwrite it. The real fix is a new package build. As of 5 November 2026, that build is still in the AlmaLinux testing repository.

The diagnosis here comes from AlmaLinux. Andrew Lukoshko, AlmaLinux Lead Architect, published it on 4 November 2026 as Call for testing - nginx fix for "no buffer space in script copy" errors. CVE (Common Vulnerabilities and Exposures) is the public ID system for security bugs.

What the error looks like

A small share of requests return HTTP 500 after the nginx security update. The same URL can succeed on one request and fail on the next. Each failure writes an [alert] line to the error log with the text no buffer space in script copy.

On AlmaLinux 9, the first CVE-2026-42533 update was ALSA-2026:66542, issued on 2026-09-11. It shipped nginx-1.20.1-28.el9_8.6.alma.1. AlmaLinux says it reproduced the problem on every AlmaLinux release that received the update.

Count the alerts

Start with a number, so you can compare it after the fix. This command counts matching lines in the current log:

sudo grep -c 'no buffer space in script copy' /var/log/nginx/error.log

The next command also searches rotated logs, compressed or not. It runs inside sudo sh -c because your normal user may not be able to read the log directory, and then the * would not expand.

sudo sh -c "zgrep -c 'no buffer space in script copy' /var/log/nginx/error.log*"

The output is one file:count line per log. A count of 0 in every file means this alert is not your problem. If your config sets a different error_log path, use that path instead.

To see which requests fail, print the last few alerts. Each line shows the client and the request.

sudo grep 'no buffer space in script copy' /var/log/nginx/error.log | tail -n 5

Find the volatile map in your config

AlmaLinux names one trigger. A set or rewrite directive uses a variable from a map marked volatile, and the value of that map contains other variables. This is the example from its post:

map $uri $cache_key {
    volatile;
    default "$scheme://$host$uri$is_args$args";
}

server {
    location /purge/ {
        set $key $cache_key;
        ...
    }
}

Your config may be split across many include files. nginx -T tests the config and also prints every config file to standard output, so one search covers all of them:

sudo nginx -T 2>&1 | grep -n -B2 -A8 volatile

Each match shows a volatile line with the lines around it. Read the map block. Note the variable name on the map line ($cache_key here), and check whether any value holds a $. Then search for where that variable is used. Replace cache_key with your own name:

sudo nginx -T 2>&1 | grep -nE '(set|rewrite) .*cache_key'

A match means your config fits the AlmaLinux trigger. Compare the matching location with the URLs in your alert lines. To see how these blocks connect, read how an nginx reverse proxy config fits together.

No match does not clear you. AlmaLinux's patch commit gives a volatile map as an example of a variable handler that runs during an outer copy. It is an example, so other paths may exist. The Rocky Linux section below shows one report that does not fit the example.

Why does a healthy config fail?

nginx builds many strings with small internal scripts. A script engine copies parts of the string into an output buffer. The security fix adds a check before each copy: is there enough room before the end of the buffer?

Red Hat's backport had a constraint. Adding a field to the script engine structure would break the ABI (application binary interface), which external modules depend on. So the el9_8.6 patch stores the buffer end in a global variable, ngx_http_script_engine_end. Its commit message reasons that workers are single-threaded and scripts do not yield.

The gap is nesting. Per AlmaLinux, the failure runs in this order:

  1. The outer set script starts to copy and records its buffer end in the global.
  2. The copy needs the volatile map variable, so nginx computes it now.
  3. The map value contains variables, so an inner script runs and writes its own buffer end to the same global.
  4. Control returns to the outer script, which checks its copy against the wrong buffer end.

The result depends on where the two buffers sit in memory. That is why the error looks random and why the same URL can pass and then fail. When the check fails, nginx logs the alert and returns 500.

Which build do you have?

rpm -q nginx
dnf module list nginx

rpm -q nginx prints the installed build. On AlmaLinux 9 with the default package, alma.1 is the affected build and alma.2 is the fix. In dnf module list nginx, the [e] mark shows the stream you enabled. These are the fixed builds that AlmaLinux lists:

  • AlmaLinux 8, nginx:1.24 stream: nginx-1.24.0-3.module_el8.10.0+4351+6f6e4e3e.5.alma.2
  • AlmaLinux 9, default: nginx-1.20.1-28.el9_8.6.alma.2
  • AlmaLinux 9, nginx:1.24 stream: nginx-1.24.0-7.module_el9.8.0+335+c30a9238.5.alma.2
  • AlmaLinux 10, default: nginx-1.26.3-6.el10_2.7.alma.1

The AlmaLinux 10 name ends in alma.1, so do not read that suffix as affected there. Compare the full name with this list.

Is the fix in the stable repos yet?

Not as of 5 November 2026. The file nginx-1.20.1-28.el9_8.6.alma.2.x86_64.rpm returned 404 in the AlmaLinux 9 AppStream package directory, and the AlmaLinux blog has no follow-up post saying that it reached production.

This can change quickly, so check it yourself first:

dnf --showduplicates list nginx

If this list shows the fixed build from your normal repos, run sudo dnf upgrade 'nginx*' and go straight to the restart step in the next section. If it does not, use the testing repository.

Install the fix from the AlmaLinux testing repo

Read this warning first. The AlmaLinux wiki says that installing packages from the Testing repo on production machines is not recommended. Try the build on a staging copy of the server if you have one. On production, you must weigh a test package against the 500 errors you see now.

These are the steps from the AlmaLinux post:

sudo dnf install -y almalinux-release-testing
sudo dnf upgrade 'nginx*' --enablerepo=almalinux-testing
rpm -q nginx

rpm -q nginx should now print a build from the list above. If you use a module stream, the testing repo offers the update only for the stream you have enabled.

The package update does not restart nginx. Until you restart it, the running workers keep the old code, even though rpm -q shows the new build.

sudo nginx -t && sudo systemctl restart nginx
systemctl is-active nginx

nginx -t checks the syntax and tries to open the files the config refers to. The restart runs only if that test passes. The last command should print active. To find other services that still run old code after an update, see how to check what needs a restart on Rocky and Alma.

On a production server, disable the testing repo now. If it stays on, a later dnf upgrade can pull other test packages.

sudo dnf config-manager --disable almalinux-testing
dnf repolist --enabled

almalinux-testing should not appear in the list.

Confirm that the alerts stopped

The AlmaLinux post checks with this command:

sudo grep 'no buffer space in script copy' /var/log/nginx/error.log

Old alerts stay in the file, so this command alone can mislead you. Use the count from earlier. Run sudo grep -c 'no buffer space in script copy' /var/log/nginx/error.log after the restart, wait for real traffic, and run it again. A count that stays the same means no new alerts.

These are AlmaLinux's own test results, so read them as a report and not as a guarantee for your config:

ChartHTTP 500 errors in 2,000 requests, AlmaLinux tests
The data behind this chart
[
  {
    "label": "AlmaLinux 9, nginx 1.20",
    "errors_before_fix": 26,
    "errors_after_fix": 0
  },
  {
    "label": "AlmaLinux 9, nginx:1.24 stream",
    "errors_before_fix": 20,
    "errors_after_fix": 0
  },
  {
    "label": "AlmaLinux 10, nginx 1.26",
    "errors_before_fix": 19,
    "errors_after_fix": 0
  }
]

On AlmaLinux 9 with nginx 1.20, errors fell from 26 to 0. The fix makes the script functions save the global buffer end before they run and restore it afterwards. The CVE protection stays in place and the ABI does not change. The commit is dated 3 November 2026 and changes ngx_http_complex_value() and ngx_http_script_run(), plus the matching stream functions.

If new alerts still appear on a fixed build, your trigger is probably different. Send the details to AlmaLinux. Its post asks for both success and failure reports, and bugs.almalinux.org is one place to send them.

Why you should not downgrade

You can undo an update with dnf history, and the alert will stop, because Red Hat's patch is what added this check to the el9 1.20.1 package. The same rollback removes the CVE-2026-42533 fix. This warning is our own conclusion from the advisories. The AlmaLinux post does not discuss downgrades.

Red Hat describes the CVE as a heap buffer overflow that an unauthenticated attacker can reach with crafted HTTP requests, when a map uses regex matching and capture variables. It rates the CVE 7.0. F5, which assigned the CVE, scores it 8.1 on CVSS (Common Vulnerability Scoring System) 3.1 and 9.2, Critical, on CVSS 4.0. The NVD (National Vulnerability Database) record shows those F5 scores and none of its own. nginx.org lists 0.9.6 through 1.31.2 as vulnerable.

Pinning the old build with dnf versionlock is worse, because the pin also blocks the next security update. If you still roll back for a short time, read Red Hat's mitigation first: avoid unnamed captures, and use named captures only in the block of the regex match. Then remove the rollback as soon as a fixed build reaches you.

Does dropping volatile work around it?

No source confirms that it does. The AlmaLinux post offers no workaround, and nothing we read says this edit is safe. Do not treat it as a fix.

The edit also changes behavior. The nginx map docs say volatile "indicates that the variable is not cacheable". Without it, nginx can reuse the value within a request. If the variables inside the map change during the request, your config then sees an old value. Someone added volatile for a reason, so find that reason before you remove it.

Does Rocky Linux or RHEL carry the same bug?

RHEL 9 carries the same code. Red Hat's nginx-1.20.1-28.el9_8.6 source, as imported into AlmaLinux's git, adds the global variable and the alert string, and it has no save and restore around nested runs. So AlmaLinux did not create this design. That confirms the code, but we did not see a failure reproduced on RHEL. RHSA-2026:66542 lists no known issue.

AlmaLinux says it reported the bug and fix to Red Hat as RHEL-300689, so that CentOS Stream and RHEL can get the fix. We could not open that ticket. Check its status yourself, and do not assume a fix date.

Rocky Linux is likely, but not confirmed. Its package directory has nginx-1.20.1-28.el9_8.6.rocky.0.1, dated 11 September 2026, and no later 1.20.1 build. Rocky builds from the same Red Hat source, so the same code is a fair inference. We could not open Rocky's own source. The AlmaLinux post does not mention Rocky. For how the two projects differ, see Rocky Linux vs AlmaLinux.

There is one user report, and it is only that. A thread on the Rocky forum shows the same alert on the Rocky build, and rolling back to el9_8.5 stopped it. The posted config has $realpath_root in fastcgi_param SCRIPT_FILENAME and shows no map, so it does not match the AlmaLinux trigger. The cause in that thread is the poster's guess, and no Rocky staff replied. We do not know whether the AlmaLinux fix covers that case.

Does upstream nginx log this on a healthy config?

By reading the source, no. Upstream commit 7ac6789, "Script: buffer overrun protection.", added this string. In the nginx 1.31.3 source, each script engine has its own end field, so there is no shared global for a nested run to overwrite. The alert should appear only on a real overflow.

This is our reading of the code. It is not a statement from the nginx team, and we did not run it. It applies to 1.31.3, which was released on 15 July 2026. It does not apply to the el9 backports. So on upstream 1.31.3, treat this alert as a real bug and report it.

What about Ubuntu?

Ubuntu has its own history with this CVE. Keep it separate from the AlmaLinux diagnosis.

  • USN-8563-2 (20 July 2026) reverted the CVE-2026-42533 fix because of ABI changes that could affect external modules. It does not mention this alert.
  • USN-8563-3 (19 August 2026) shipped a new fix, and USN-8563-4 reverted it the same day.
  • The changelog in Launchpad bug 2164558 ties that second revert to no buffer space in script copy. Reports there involve FastCGI and PHP-FPM, and the thread gives no detailed root cause.
  • USN-8563-5 (14 September 2026) shipped what it calls a better fix, 1.24.0-2ubuntu7.18 on 24.04.

So Ubuntu saw the same string, but no source says that Ubuntu's patch and the el9 patch failed for the same reason. The AlmaLinux steps do not apply to Ubuntu.

FAQ

What does "no buffer space in script copy" mean in nginx?

nginx checked whether a string fits in its output buffer before a copy, and the check failed. nginx logs the message at alert level and returns HTTP 500. On AlmaLinux builds with the CVE-2026-42533 update, AlmaLinux says the check can fail wrongly, because the buffer end sits in one global variable that nested scripts overwrite.

Why do only some requests fail with HTTP 500?

AlmaLinux says the result depends on where two buffers land in memory. The outer script compares its copy with the buffer end of an inner script. Sometimes that comparison still passes, so a small share of requests fail and the same URL can work on the next try.

How do I fix this error on AlmaLinux 9?

Install nginx-1.20.1-28.el9_8.6.alma.2 or later, then restart nginx. As of 5 November 2026 it is in the testing repo: run sudo dnf install -y almalinux-release-testing, then sudo dnf upgrade 'nginx*' --enablerepo=almalinux-testing, then sudo nginx -t && sudo systemctl restart nginx. On production, run sudo dnf config-manager --disable almalinux-testing afterwards.

Can I downgrade nginx to stop the alert?

A downgrade stops the alert, but it also removes the CVE-2026-42533 fix, which covers a heap buffer overflow that a remote attacker can reach with crafted requests on some map configs. Use the fixed build instead. If you must roll back for a short time, read Red Hat's mitigation for the CVE first and plan to update again soon.

Does the alert mean my nginx config is wrong?

On the affected el9 builds, no. A valid config with a volatile map used by set or rewrite can trigger it. On upstream nginx 1.31.3, the source suggests the alert appears only on a real overflow, so treat it as a real bug there and report it.

Was this article useful?