By Greg Nowak. Updated 18 October 2026.
An NGINX upgrade can look routine until an older application starts failing only after a quiet period, or a login flow behaves differently under concurrent use. NGINX 1.30 changes how its default HTTP proxy connection to a backend works: it uses HTTP/1.1 and keeps upstream connections available for reuse. Most applications should benefit, but inherited configuration and unusual backends deserve a deliberate check.
For a business owner or agency team, this is a manageable compatibility review, not a reason to delay every upgrade. Identify which applications sit behind NGINX, test the journeys that matter, and agree who will make the rollback call. As of 18 October 2026, NGINX lists 1.30.6 (released 14 October) as its current stable release and 1.31.7 as mainline; check your package vendor’s history when planning the actual update.
proxy_http_version: the short answer
proxy_http_version sets the HTTP version NGINX speaks to a proxied backend. Up to 1.29.6 the default was 1.0, which closes the backend connection after every request. From mainline 1.29.7 and in every 1.30.x stable release the default is 1.1, NGINX no longer sends a Connection header to the backend by default, and the upstream keepalive cache is on by default. You only need to write proxy_http_version 1.1; yourself on an older build, or proxy_http_version 1.0; to force the old behaviour on one route.
Older guides add proxy_set_header Connection ""; to clear the header. On 1.30 that is already the default. Setting Connection "keep-alive" is not needed either: an HTTP/1.1 connection stays open unless one side sends close.
What changed in NGINX 1.30?
The new defaults arrived in mainline version 1.29.7 and carried into the 1.30 stable branch. proxy_http_version now defaults to 1.1 instead of 1.0. Upstream keep-alive caching is enabled by default, equivalent to keepalive 32 local;. That can reduce repeated connection setup between NGINX and an HTTP backend.
The number 32 is the maximum number of idle upstream connections cached per worker process. It does not limit active or total backend connections. If you are sizing a backend, consider the worker count, peak traffic and the backend’s own connection limit rather than treating 32 as a safety cap.
| Backend or configuration | First action | Test that matters |
|---|---|---|
| Modern HTTP application | Keep the new defaults | Response times, 5xx rates and backend connections |
| Older or vendor-managed application | Test reuse before rollout | Login, uploads and the first request after an idle period |
| NTLM or Negotiate authentication | Review connection-bound authentication setup | Concurrent sessions and re-authentication |
Explicit keepalive 32; |
Decide whether reuse across locations is intended | Routes that reach the same upstream address |
| Backend proven to need fresh connections | Make a route-specific exception | Reproduce the fault, then retest the fix |
Audit the configuration NGINX actually loads
Start with the running build and the complete loaded configuration. A shared include, hosting panel or deployment template can affect a route even when its local file looks straightforward. These commands help locate the relevant settings:
sudo nginx -V
sudo nginx -T 2>&1 | grep -nE 'proxy_pass|proxy_http_version|proxy_set_header[[:space:]]+Connection|keepalive|ntlm'
sudo nginx -tnginx -V shows build options; nginx -T tests and prints the configuration, including included files. Keep its output within your operations team because it may reveal internal addresses or other sensitive settings. The search is a starting point: follow each proxy_pass route to its upstream and record the application owner, especially where several clients share an NGINX instance.
Review proxy_set_header directives together. NGINX inherits them from a parent level only when the current level defines none. Adding one header inside a location can therefore replace a larger inherited set. Check the effective headers before removing an old Connection line or adding an exception.
Keep configuration changes small and intentional
Older configurations often contain proxy_http_version 1.1; and proxy_set_header Connection ""; solely to enable upstream reuse. NGINX says those lines are no longer needed for that purpose. They can remain while you validate the upgrade; remove redundant lines later through a reviewed change, particularly if a shared include serves several applications.
An explicit keepalive 32; needs a closer look. Without local, a cached connection can be reused across locations that reach the same upstream address. The new implicit default keeps those caches local to each location. If that separation is what you want, express it clearly in the upstream block:
upstream application_backend {
server 127.0.0.1:8080;
keepalive 32 local;
}Do not tune keep-alive request counts or timeouts just because the directives exist. First establish whether the backend has a documented limit, whether sockets are under pressure, or whether a reproducible failure points to an idle connection issue.
Test awkward backends on real user journeys
A homepage check will miss many compatibility faults. Exercise sign-in and sign-out, simultaneous users, administrative actions, larger uploads and the first request after the backend has sat idle. Compare application logs with NGINX errors and response timings. For NTLM or Negotiate, inspect how authentication is bound to upstream connections and test with concurrent sessions; do not assume a single successful login proves the setup is safe.
If testing shows that one backend truly requires HTTP/1.0 and a closed connection, contain the change to its route:
location /legacy-app/ {
proxy_pass http://legacy_backend;
proxy_http_version 1.0;
proxy_set_header Connection "close";
}Document why the exception exists, who owns the backend and what would allow its removal. A server-wide downgrade would also discard reuse for applications that work well with the new defaults.
502 Bad Gateway or 504 from nginx/1.30.x right after the upgrade?
The version in the error page, nginx/1.30.2 or nginx/1.30.4 for example, only says which NGINX produced the page. It does not mean that release is broken. A 502 means NGINX did not get a valid response from the backend; a 504 means the backend did not answer in time. If either is new after moving to 1.30, connection reuse is the first suspect.
The usual pattern: the backend closes an idle connection after a few seconds, NGINX still has that connection in its keepalive cache and sends the next request down it, and the request fails. The error log then shows upstream prematurely closed connection while reading response header from upstream. Check /var/log/nginx/error.log for that line and compare the backend's idle timeout with NGINX's upstream keepalive_timeout, which defaults to 60 seconds.
upstream application_backend {
server 127.0.0.1:8080;
keepalive 32 local;
keepalive_timeout 5s; # shorter than the backend's own idle timeout
}Keep NGINX's timeout shorter than the backend's, so NGINX is the side that closes idle connections. If the backend has no keep-alive support at all, use the per-route exception above instead. A new 504 with the same log line has the same cause; if the log says upstream timed out instead, the backend is slow and the upgrade is a coincidence.
Quick answers
NGINX 1.30 release dates
From the nginx.org changelog: 1.30.0 on 14 April 2026, 1.30.1 on 13 May, 1.30.2 on 22 May, 1.30.3 on 17 June, 1.30.4 on 15 July, 1.30.5 on 15 September and 1.30.6 on 14 October 2026. 1.30.3 through 1.30.6 each carry security fixes, so run the newest 1.30.x rather than the one your distribution shipped first.
NGINX 1.30 vs 1.31
1.30 is the stable branch and gets bug and security fixes only. 1.31 is mainline, where new features land first; 1.31.7 is current as of October 2026, released the same day as 1.30.6. The upstream keepalive change is in both, since it arrived in 1.29.7 before the branches split. For production, stable is the usual choice.
What does nginx/1.30.2 in an error page mean?
The server that produced the page runs NGINX 1.30.2. If it is not your server, there is nothing to upgrade on your side; the error is between that site and its backend. If it is yours, 1.30.2 is four releases behind 1.30.6 and missing several security fixes.
Roll out with evidence and a way back
Before the upgrade, capture a short baseline: 502 and 504 rates, upstream connection and response times where logged, authentication failures, backend connection counts and relevant application errors. Test the higher-risk routes first, then canary production traffic if your setup permits it. Agree on a monitoring window and a stop condition, such as a sustained rise in backend errors or a failed critical login journey.
Keep the previous package and configuration deployment path available until the checks pass. The useful handover is an application inventory, the configuration decisions, test results, monitoring ownership and a rollback procedure. If your team is juggling inherited client setups and vendor systems, Greg can help plan and coordinate the upgrade.
Related on GrN.dk
- Nginx 1.30 Changed Upstream Connections: What to Test Before You Upgrade
- Agentic AI: What It Is, How It Works, and When to Use It
- Before You Buy a GPU: Test Your Team’s Local AI Workload
Need help with this kind of work?
Plan your NGINX upgrade with Greg Get in touch with Greg.