We are pleased to announce that NGINX Plus Release 21 (R21) is now available. Based on NGINX Open Source, NGINX Plus is the only all-in-one load balancer, content cache, web server, and API gateway. With more than 450 million web sites relying on NGINX, NGINX Plus R21 is more reliable and more secure than ever before, primarily focusing on bug fixes and stability improvements from NGINX Open Source.
New features of NGINX Plus R21 include:
- Dynamic gRPC proxying – We’ve added variable support when passing gRPC connections to backend gRPC services. This enables you to dynamically route gRPC connections to groups of services based on client attributes.
- NGINX JavaScript module enhancements – The NGINX JavaScript module (njs) has been updated to version 0.3.9, with several bug fixes and additional functional enhancements related to subrequests and filesystem support.
Important Changes in Behavior
- Acceptable requests – In accordance with RFC 7230, NGINX Plus no longer allows client requests with multiple
Hostheaders. - New operating systems supported – Alpine Linux 3.11.
- Older operating systems no longer supported – 32‑bit platforms (i386 architectures).
Investing in Quality
Efficient software and code quality are central tenets of how we build NGINX, both open source and NGINX Plus.
The NGINX team employs all the modern CI/CD and automated testing tools that you expect of any commercial software. Daily testing of the active development branch shows a remarkably low “defect density” of just 0.01 defects per 1000 lines of code, compared to an average density of 0.7 defects per 1000 lines for codebases of a similar size.
We also commission external and independent penetration tests and code reviews for both open source and NGINX Plus components. The most recent of these penetrations tests and code reviews identified several issues that are addressed in this release.
Bug Fixes
In total, NGINX Plus R21 includes fixes for 14 bugs:
- Socket leak when using HTTP/2 (two separate bugs)
- Socket leak when using subrequests in the njs module and the
aiodirective - Potential memory exhaustion in the WebDav module
- Potential memory disclosure in the MP4 module
- Status code
494was returned instead of400when errors with code494were redirected with theerror_pagedirective - Timeout might occur while handling pipelined requests in an SSL connection
- Segmentation fault might occur in a worker process if OCSP stapling was used
- Segmentation fault might occur at start or during reconfiguration if the configuration included the
rewritedirective with an empty replacement string - Segmentation fault might occur in a worker process if the
breakdirective was used in conjunction with thealiasdirective, or in conjunction with theproxy_passdirective with a URI - Only the first
Transfer-Encodingrequest header was processed - The
Locationresponse header line might contain garbage if the request URI was rewritten to one containing a null character - Requests with bodies were handled incorrectly when returning redirects with the
error_pagedirective - Bug in the
debug_pointsdirective when using HTTP/2
Please note that none of these bugs were critical, and there are no associated CVE records.
Investing in the NGINX Plus Roadmap
At the time of this release, we are working hard on our 2020 roadmap. Later this year we expect to make available a production‑grade implementation of HTTP/3 (aka QUIC). If you are interested in following or testing this technology then watch out for experimental patches in the coming weeks.
New Features in Detail
Dynamic gRPC Proxying
NGINX Plus R15 introduced support for routing and load balancing gRPC traffic to upstream groups. You can leverage NGINX Plus to route gRPC traffic by including the grpc_pass directive.
NGINX Plus R21 introduces variable support in the grpc_pass directive to provide dynamic, API‑driven routing policies that extend to gRPC workloads. This makes it possible to meet use cases such as:
- A/B testing – Statistically distribute gRRC requests across several upstreams to determine which one performs better.
- Debug routing – Route traffic to a production gRPC service, but route requests with specific attributes (source IP addresses, gRPC metadata) to a debug gRPC service.
The following configuration is a sample implementation of debug routing.
Loading gist…
In line 1, we define a key‑value store that can use network ranges as the key (enabled by the type=ip parameter). Line 2 specifies that the $greeter_upstream variable is evaluated by performing a lookup in the grpc-greeter key‑value store, using the client IP address ($remote_addr) as the key.
On line 10, we specify grpc://$greeter_upstream as the parameter to the grpc_pass directive, for TLS termination and dynamic routing of gRPC requests based on the client’s IP subnet.
For example, you can run the following command on the NGINX Plus instance to route requests originating from the 192.168.80.0/24 subnet to grpc-servers-greeter-debug:
To switch gRPC traffic to the production service group (grpc-servers-greeter-prod), run the following command:
Enhancements to the NGINX JavaScript Module
The NGINX JavaScript module (njs) has been updated to version 0.3.9 with several bug fixes and some functional enhancements related to subrequests and filesystem support.
Subrequests
The r.subrequest function enables njs code to make asynchronous HTTP requests to any URI. This has many possible use cases, one notable example being API calls to an external authentication server, for example OAuth 2.0 token introspection. This release brings two significant enhancements to subrequests: promises and detached subrequests.
[Editor – The following two sample use cases are just some of many for the NGINX JavaScript module. For a complete list, see Use Cases for the NGINX JavaScript Module.]
Promises
Subrequests typically include a callback function that processes the response of the subrequest. A callback function can now be omitted, using JavaScript promises as a way of processing responses inline with the calling code. The following example illustrates how successive subrequests can be chained together in a single code sequence without using callbacks.
Loading gist…
Detached Subrequests
Subrequests are asynchronous, and previously they had to be invoked from a js_content directive. Now subrequests can also be triggered from a js_set directive during variable evaluation. These “detached” subrequests still work asynchronously, but do not return any data to the calling function, and any response is ignored.
The following sample code uses detached subrequests to send a copy of the request headers to a security information and event management (SIEM) system if the total amount of data exchanged exceeds 1 MB.
[Editor – The following configuration has been updated to use the js_import directive, which replaced the js_include directive in NGINX Plus R23<.htmla>. For more information, see the reference documentation for the NGINX JavaScript module – the Example Configuration section shows the correct syntax for NGINX configuration and JavaScript files.]
Loading gist…
The JavaScript code is then executed at the log phase by asking for variable evaluation when we write the access log.
Loading gist…
Filesystem
The JavaScript filesystem object fs has been enhanced to support promises for asynchronous operations. In addition, there are new filesystem methods: access(), realpath(), symlink(), and unlink().
Upgrade or Try NGINX Plus
If you’re running NGINX Plus, we strongly encourage you to upgrade to NGINX Plus R21 as soon as possible. You’ll also pick up a number of additional fixes and improvements, and it will help NGINX to help you when you need to raise a support ticket.
Please carefully review the new features and changes in behavior described in this blog post before proceeding with the upgrade.
If you haven’t tried NGINX Plus, we encourage you to try it out – for security, load balancing, and API gateway, or as a fully supported web server with enhanced monitoring and management APIs. You can get started today with a free 30-day trial. See for yourself how NGINX Plus can help you deliver and scale your applications.
About the Author

Related Blog Posts
Secure Your API Gateway with NGINX App Protect WAF
As monoliths move to microservices, applications are developed faster than ever. Speed is necessary to stay competitive and APIs sit at the front of these rapid modernization efforts. But the popularity of APIs for application modernization has significant implications for app security.
How Do I Choose? API Gateway vs. Ingress Controller vs. Service Mesh
When you need an API gateway in Kubernetes, how do you choose among API gateway vs. Ingress controller vs. service mesh? We guide you through the decision, with sample scenarios for north-south and east-west API traffic, plus use cases where an API gateway is the right tool.
Deploying NGINX as an API Gateway, Part 2: Protecting Backend Services
In the second post in our API gateway series, Liam shows you how to batten down the hatches on your API services. You can use rate limiting, access restrictions, request size limits, and request body validation to frustrate illegitimate or overly burdensome requests.
New Joomla Exploit CVE-2015-8562
Read about the new zero day exploit in Joomla and see the NGINX configuration for how to apply a fix in NGINX or NGINX Plus.
Why Do I See “Welcome to nginx!” on My Favorite Website?
The ‘Welcome to NGINX!’ page is presented when NGINX web server software is installed on a computer but has not finished configuring
