Recovering from a Failed NGINX Plus Upgrade: 'module "M" version X instead of Y'

NGINX | March 14, 2017

If you are using dynamic modules, you might see an error like this during the upgrade to a new NGINX or NGINX Plus release:

[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

The most likely reason is that you haven’t upgraded the specified dynamic module (.so file):

  • If you are running NGINX Open Source, dynamic modules must be compiled against the version you are upgrading to.
  • If you are running NGINX Plus, dynamic modules must be compiled against the NGINX Open Source version that corresponds to the NGINX Plus release you are upgrading to.

For the sake of brevity we’ll refer to NGINX Plus only from now on.

Don’t Panic!

Rest assured that this error message does not indicate that your NGINX Plus server is down. NGINX Plus upgrades are seamless, so the old version continues running when an upgrade fails. However, the upgrade is incomplete and your system is in an inconsistent state:

  • NGINX Plus processes in memory are running the old version
  • All of the files on disk relating to NGINX Plus correspond to the new version
  • The dynamic module mentioned in the error message is compiled against the old version

Do not manually restart nginx, or reboot the system. Doing so will cause downtime because new NGINX Plus processes cannot start while there are dynamic modules out of sync with the new NGINX Plus release.

Note that the error message relates only to the first incompatible module found during the upgrade process, so it is important to find all load_module directives in your configuration and ensure that every module is compiled against the appropriate NGINX version. Correct versions of all NGINX‑authored and certified third‑party dynamic modules are provided for each NGINX Plus release<, so you need to recompile only non‑certified modules.This article describes how to safely complete the upgrade process.

What Went Wrong?

NGINX 1.11.5 and NGINX Plus R11 introduced the ability to compile dynamic modules against NGINX Open Source and load them into NGINX Plus. This binary compatibility requires the module and NGINX Plus to share the same base open source version. Upgrading NGINX Plus without first installing dynamic modules built against the corresponding NGINX Open Source version fails because of this version mismatch.

If your dynamic module was supplied by a third‑party vendor then you need to contact the vendor for a new version, matched to the NGINX version for the NGINX Plus release you intend to upgrade to. If your dynamic module was compiled from source (and you have access to the sources) then continue reading.

The Road to Recovery

Step 0: Prepare the Build Environment

We strongly recommend that you compile dynamic modules on a separate system, which we refer to here as the “build environment”. Doing so minimizes the risk and complexity of the system where you are running NGINX Plus with the dynamic module (we refer to this as the “production environment”). The build environment must have the same operating system and version as the production environment; in addition, the following components must be installed:

  • UnZip utility
  • Compiler and make utility
  • Perl‑compatible regular expressions library (development files)
  • Zlib compression libraries (development files)

To ensure your build environment has these prerequisites installed, run the following command.

  • For Ubuntu/Debian:[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop
  • For CentOS/RHEL/Oracle Linux: [@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Step 1: Obtain NGINX Open Source

  1. Working in the production environment, run the following command to identify the NGINX Open Source version that corresponds to the running NGINX Plus release. It’s highlighted in orange in this output: NGINX 1.11.10, which corresponds to NGINX Plus R12.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop
  2. Working in the build environment, download the sources for the appropriate NGINX Open Source version.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Step 2: Obtain the Dynamic Module Sources

Copy the source code for the dynamic module to the build directory of your choice. Here we copy a sample NGINX “hello world” module from its GitHub repository.

[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Step 3: Compile the Dynamic Module

  1. Compile the dynamic module by first running the NGINX configure script with the --with-compat argument to make the dynamic module binary‑compatible with NGINX Plus. Then run make modules to compile just the module.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop
  2. Verify that the build process has created the dynamic module as a .so file in the objs subdirectory.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop
  3. Create a copy of the module file with the NGINX Open Source version in the filename. This makes it simpler to manage multiple versions of the dynamic module in the production environment.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Step 4: Copy the Dynamic Module to the Production Environment

Because we created the dynamic module with the NGINX Open Source version in the filename, we can safely copy it to the production environment without affecting operation.

[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Step 5: Swap Over the Dynamic Module

Working in the production environment, swap in the new .so file to replace the current one. This is safe to do at this point because dynamic modules are loaded into memory only when nginx restarts or the configuration is reloaded.

[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Step 6: Complete the Upgrade of NGINX Plus

  1. Run the following command to test that the module version is correct and that NGINX Plus is ready to complete the upgrade process.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop
  2. Complete the upgrade process so that NGINX Plus is using the new release and dynamic modules.[@portabletext/react] Unknown block type "codeBlock", specify a component for it in the `components.types` prop

Preventing the Upgrade Failure

The next time you upgrade NGINX Plus, you can save time and avoid errors by following these instructions before the upgrade so that updated dynamic modules are already available when you start the upgrade process.


Share

About the Author

Liam Crilly
Liam CrillySr Director, Product Management

More blogs by Liam Crilly

Related Blog Posts

Automating Certificate Management in a Kubernetes Environment
NGINX | 10/05/2022

Automating Certificate Management in a Kubernetes Environment

Simplify cert management by providing unique, automatically renewed and updated certificates to your endpoints.

Secure Your API Gateway with NGINX App Protect WAF
NGINX | 05/26/2022

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
NGINX | 12/09/2021

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
NGINX | 01/20/2021

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
NGINX | 12/15/2015

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?
NGINX | 01/01/2014

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

Deliver and Secure Every App
F5 application delivery and security solutions are built to ensure that every app and API deployed anywhere is fast, available, and secure. Learn how we can partner to deliver exceptional experiences every time.
Connect With Us
Recovering from a Failed NGINX Plus Upgrade: 'module "M" version X instead of Y' | F5