Knowing where traffic comes from can help you decide where it goes. NGINX Open Source 1.31.7 brings GeoIP2 and GeoLite2 database support to the existing native GeoIP modules, giving users a straightforward path to current geolocation data.
This release also adds modern HTTP/2 prioritization, improves reloads and binary upgrades for BPF-enabled QUIC deployments, and includes fixes informed by community investigation and feedback.
Release highlights
- Native GeoIP2 database support: Use modern geolocation databases with familiar NGINX directives and variables.
- RFC 9218 HTTP/2 priorities: Schedule responses using explicit urgency and incremental delivery signals.
- BPF-based QUIC reload and binary upgrade: Improve connection routing during configuration reloads and executable upgrades.
- Bug fixes and smaller enhancements: Updates to certificate validation, WebDAV destination handling, configuration validation, and Windows builds.
Native GeoIP modules gain GeoIP2 support
What’s new: NGINX Open Source 1.31.7 adds MaxMind DB (MMDB) support to its existing HTTP and stream GeoIP modules. The geoip_country, geoip_city, and geoip_org directives can now read modern GeoIP2 and GeoLite2 databases, while retaining the familiar $geoip_* variable names (nginx/nginx#1655).
For existing native GeoIP users, migration starts with pointing the same directives at an MMDB database:
geoip_country /usr/share/GeoIP/GeoLite2-Country.mmdb;
geoip_city /usr/share/GeoIP/GeoLite2-City.mmdb;
For source builds, configure detects the available libraries: libmaxminddb enables MMDB support, while libGeoIP enables legacy database support. Builds with both libraries can use both formats during migration. If neither library is found, configure fails.
MMDB data is organized differently from the legacy databases, so a few variables are filled differently:
$geoip_country_code3and$geoip_city_country_code3are converted: MMDB stores only two-letter country codes, so NGINX derives the three-letter codes from a built-in ISO 3166-1 table.$geoip_orgchecks four fields in turn:autonomous_system_organization,isp,organization, anddomain, matching the legacy ASNum, ISP, Org, and Domain editions.$geoip_regionand$geoip_region_namecome from the first subdivision: Their values may differ from the legacy database’s.$geoip_dma_codemay be empty: It comes fromlocation.metro_code, which MaxMind has deprecated.$geoip_area_codeis never set: MMDB has no matching field.
Why it matters: MaxMind’s GeoIP Legacy format reached end of life in 2022, with its final database snapshot published in January 2023. Configurations relying on those databases have been working with increasingly stale data.
This update provides a path to maintained databases for regional routing, localized content, location-based traffic policies, and log enrichment—without adopting a different configuration model.
Already using the community GeoIP2 module? You can continue using it. Native MMDB support is another option, not a drop-in replacement for the community module’s configuration or full feature set. Existing native GeoIP users should also review field compatibility and build requirements before migrating.
[NEEDS SPECIFICS: confirm whether the nginx.org nginx-module-geoip packages for 1.31.7 are built against libmaxminddb. nginx/pkg-oss hasn’t been bumped past 1.31.6 yet, so the repo can’t answer it. If they aren’t, package users need to build from source to read MMDB files, and this section should say so.]
RFC 9218 HTTP/2 priorities
What’s new: The HTTP/2 module now implements RFC 9218, “Extensible Prioritization Scheme for HTTP.” Clients signal priority through the Priority request header or PRIORITY_UPDATE frames, using two parameters:
- Urgency: A level from 0 through 7, where lower values are more urgent. The default is 3.
- Incremental delivery: A flag indicating whether a response can be processed progressively.
For example:
Priority: u=1
Priority: u=5, i
NGINX combines client priority signals with any response-side Priority header to influence delivery scheduling, without modifying the request’s priority header forwarded upstream. Where both set a parameter, the response’s value wins.
NGINX orders outgoing frames by urgency first, then non-incremental ahead of incremental, then by request order. RFC 9218 also recommends sending non-incremental responses of equal urgency one at a time; NGINX orders them but doesn’t strictly serialize them.
The old RFC 7540 dependency-tree scheme and its weights are removed, and RFC 7540 priority signals are now ignored. RFC 9218 support is enabled without an additional directive (nginx/nginx#1520).
Why it matters: RFC 9218 replaces the complex priority tree with a simpler, explicit scheme. Under contention, a browser can mark render-blocking CSS as more urgent than background traffic, allowing NGINX to favor the more important response—even when the lower-priority request arrived first.
The pull request includes a test where two 10 MB downloads share a link shaped to 50 Mbit/s. With no priority signals, the file requested first finished first. With the second request marked u=1 and the first u=5, the second finished at 2.57 seconds and the first at 3.42 seconds.
Response-side priority signals also give origins a way to communicate delivery preferences to downstream intermediaries.
QUIC: BPF-based reload and binary upgrade
What’s new: NGINX updates its BPF-based QUIC routing to support configuration reloads and binary upgrades without relying on SO_COOKIE.
Listener sockets handle new connections, while per-worker sockets keep established traffic routed to the appropriate worker. During a reload, new workers accept new connections while old workers continue draining existing sessions. The routing scheme also supports transitioning between master processes during a binary upgrade (nginx/nginx#1756).
A follow-up fix addresses upgrades from versions built before this change, where an empty NGINX_BPF_MAPS environment variable could prevent the new binary from starting (nginx/nginx#1813).
Why it matters: Previously, a reload or binary upgrade with quic_bpf enabled could route new connections to workers that were shutting down or had already exited, leaving those connections hanging.
This update closes that operational gap and is an incremental step toward productionizing NGINX’s experimental HTTP/3 and QUIC support. It does not change the experimental status of that support. Broader readiness work is tracked in nginx/nginx#1323.
Stability and bug fixes
The two TLS fixes ship in the same pull request, and both concern a connection that fails partway through a read. The QUIC fix ships with the buffer-size validation in the upgrade notes below.
- IP-address certificate validation: NGINX now checks IPv4 and IPv6 server names against certificate IP-address subject alternative name (SAN) entries, enabling correct certificate validation for upstream connections made by IP address (nginx/nginx#1264).
- Cached
X-Accel-Redirectresponses no longer crash a worker: If theX-Accel-Redirectheader was cached, which happens whenproxy_ignore_headerstells NGINX to ignore it, and the cached response was later served with different settings, a worker could crash with a segmentation fault or log “request count is zero” alerts. NGINX no longer finalizes the upstream request before its cleanup handler is installed. This fix landed without a pull request. - WebDAV destination validation: Additional checks for COPY and MOVE requests prevent destinations from escaping an
aliasroot. Such requests are now rejected with 400; locations that userootwere never affected (nginx/nginx#1764). - TLS error handling: Improved handling of a TLS 1.3 connection-reset case avoids a subsequent write that could produce misleading
[crit] SSL_write() failederrors with newer OpenSSL versions (nginx/nginx#1271). - A TLS connection reset is reported as an error: NGINX treated an
SSL_read()failure with an empty OpenSSL error queue as the peer closing withoutclose_notify, and that test also caught TCP-level errors such asECONNRESET. Only a clean TCP close is treated that way now, so connection resets produceSSL_read() failederrors, the way NGINX already reports a reset on a plain TCP connection (nginx/nginx#1271). - QUIC connections keep a frame limit of at least 10,000: Since NGINX 1.27.5, the per-connection frame threshold could drop to a few frames, or none, when
http3_stream_buffer_sizewas set to a small value, and connections could close with “quic flood detected” in the logs. The previous hardcoded minimum of 10,000 frames now applies again (nginx/nginx#1644). - Windows build updates: Win32 builds now use OpenSSL 3.5.9 and PCRE2 10.49 (nginx/nginx#1816).
Also fixed in NGINX 1.31.6
NGINX 1.31.6 shipped on September 15, 2026. It was a small release focused on bug fixes. If you’re upgrading from NGINX 1.31.5 or earlier, NGINX 1.31.7 also includes these fixes:
- Binary upgrade works with a Control API socket and the Perl module: With a Control API socket specified, binary upgrade refused to work if the new binary was built with
ngx_http_perl_module. The Perl module replaces the process environment when it creates an interpreter during configuration parsing, so the control socket wasn’t inherited. NGINX now reads it from the environment before parsing the configuration, the same way it handles inherited listening sockets (nginx/nginx#1760). - A predicate location that fails to evaluate ends the request: If evaluating the variable in a predicate location failed, NGINX ignored the error and treated the predicate as false. The error now ends the request (nginx/nginx#1750).
- Errors in nested location lookups end the request too: After a prefix location matched, an error matching a regex or predicate location nested inside it could be ignored when more regex or predicate locations were configured at the current level. Such an error now ends the request (nginx/nginx#1751).
- A corrupted geo binary base is caught before it’s used: With the
geodirective’srangesparameter, a corrupted binary base file could cause a segmentation fault while NGINX read the configuration. NGINX now verifies the file’s CRC32 checksum before converting the offsets stored in it into pointers (nginx/nginx#1739).
Upgrade notes
- Zero-size buffers are now rejected: NGINX now rejects
0values for affected buffer-size directives during configuration validation, preventing read failures and potential worker CPU spins. Affected settings include client body and header buffers, proxy buffers, stream preread buffers, HTTP/3 stream buffers, MP4 buffers, SSL buffers, and subrequest output buffers. If your configuration explicitly sets an affected buffer size to0, remove the setting or choose an appropriate nonzero value before upgrading. Validate withnginx -t; it now reports an error for a buffer size of zero. Started by community contributor kh-lee (nginx/nginx#1345) and finished by the team (nginx/nginx#1644). - IP addresses match only IP-address SAN entries: With the new IP-address certificate validation, an IP address is no longer matched against a certificate’s DNS name (
dNSName) entries or its common name. A certificate that lists an upstream’s IP address only in one of those places now fails verification. If you verify upstream certificates by IP address, check that each one lists the address as an IP-address SAN entry before you upgrade (nginx/nginx#1264).
Community recognition
Thank you to everyone whose investigation, proposed patches, and testing helped shape NGINX Open Source 1.31.7.
Community inspired development work
The QUIC reload and binary-upgrade improvements build on work from Gabriel Clima, who submitted nginx/nginx#1219 to address QUIC reload handling and diagnosed an IPv6 routing issue, and Konstantin Adzer, who prepared a focused follow-up in nginx/nginx#1686. The team’s shipped implementation uses a different routing mechanism, informed by that investigation.
Separately, kh-lee proposed rejecting zero-size client body buffers in nginx/nginx#1345, after a CPU-spin issue surfaced in Ingress-NGINX. The team extended that approach to all affected buffer-size directives in nginx/nginx#1644.
Want your name in NGINX 1.31.8?
Pick up an open issue, propose an improvement, or fix a bug you have encountered. The contributing guide explains how to get started.
Getting started
NGINX Open Source 1.31.7 is available now as source code and as binary packages for major Linux distributions.
- Download source and packages: Visit nginx.org.
- Release notes and changes: Read the full CHANGES log.
- Documentation: Visit the NGINX documentation.
- GeoIP2 deep dive: Stay tuned for a follow-on GeoIP2 blog.
Stay tuned to the NGINX Blog for more release updates and technical deep dives.
Keeping NGINX up to date
NGINX releases include important fixes and ongoing improvements. We encourage users to stay current with the latest version. NGINX Open Source 1.31.7 fixes five security issues: the buffer overflow when using alias with rewrite in CVE-2026-15176, the buffer overflow in script evaluation in CVE-2026-93479, the request body injection in HTTP/3 in CVE-2026-95101, the session forgery when using TLS session tickets in CVE-2026-97629, and the use-after-free when using asynchronous file I/O in CVE-2026-97205. NGINX Open Source 1.31.6 fixed the HTTP/3 heap buffer overflow in CVE-2026-90439. Each CVE links to its official F5 advisory.
To stay informed, subscribe to F5 notifications and select the relevant advisory updates.


