How to Fix NGINX 502 Errors Now!

Published:27 September 2022 - 9 min. read

Block over 3 billion compromised passwords & strengthen your Active Directory password policy. Try Specops Password Policy for free!

As a system administrator, you know how annoying getting paged at (mostly) the wrong time whenever a site under your able hand produces errors. Indeed, you’ve seen the NGINX 502 errors, one of the most annoying errors to deal with. But no worries. This tutorial has got you covered!

In this tutorial, you’ll learn how to fix the NGINX 502 errors in this practical, scenario-based tutorial featuring NGINX and a PHP-FPM upstream app server.

Read on and save the day from NGINX 502 errors!

Prerequisites

  • Two Linux machines to host NGINX and PHP-FPM – This tutorial uses Fedora 35 on both machines with hostnames wbserver and appserver.
  • PHP-FPM installed on the appserver machine to serve as an upstream server – This tutorial uses PHP-FPM 8.1.

Installing NGINX and Configuring a 502 Error Page

With all the prerequisites in place, it’s time to install NGINX and enable the service to start at bootup. You’ll later configure an error page to demonstrate how to fix the NGINX 502 error.

1. Log in to the NGINX-hosting machine (wbserver).

2. Execute the dnf install command below to install nginx and its dependencies.

sudo dnf install -y nginx

You’ll see an output like the one below, signifying that the installation of NGINX version 1.22.0 is starting.

Installing NGINX
Installing NGINX

3. After installing NGINX, run the following systemctl command to start the nginx service –now and enable the service to start at bootup.

sudo systemctl enable --now nginx.service
Starting the NGINX service
Starting the NGINX service

4. Now, open your favorite web browser, and navigate to http://localhost, which will be your test browser for the rest of the tutorial.

As shown below, you’ll see the default Fedora Webserver Test Page if all goes well.

Viewing the default fedora homepage
Viewing the default fedora homepage

5. Create an HTML file with your favorite text in the /usr/share/nginx/html directory called 502.html. Populate the code below to the HTML file, which prints a 502 error message.

By default, NGINX uses a single error page for all server-related errors. But this HTML file enables you to identify 502 errors.

<html>
  <head>
    <title>502: Error</title>
    <meta charset="utf-8">
  </head>
  <body>
    <h1 style="text-align:center" >Error 502: Bad gateway</h1>
    <p style="text-align:center">Sorry, but the web server received an invalid response while contacting the upstream server.</p>
  </body>
</html>

6. Run the bash commands below, which don’t provide output, but perform the following:

  • Append the appserver IP address to the hosts file. Doing so enables you to refer to the machines by domain names as if using an external DNS service.

Be sure to replace 192.168.8.171, and 192.168.8.176 with your own IP addresses throughout this tutorial.

sudo bash -c "echo '192.168.8.171 wbserver' >> /etc/hosts"
sudo bash -c "echo '192.168.8.176 appserver' >> /etc/hosts"

7. Create a new file (ata-block.conf) in the custom configuration directory for NGINX (/etc/nginx/conf.d/).

vi /etc/nginx/conf.d/ata-block.conf

8. Finally, add the following code into the ata-block.conf file.

The code below configures the NGINX webserver to forward all requests for .php files to appserver’s port 9000 and serve the 502.html file for all 502 errors.

server {
  listen 0.0.0.0:80;
  server_name wbserver;
  
  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
  }

  # send all .php requests to external php-fpm server
  location ~ \.php$ {
    fastcgi_pass appserver:9000;
    fastcgi_index index.php;
    include fastcgi.conf;
  }
  
  # redirect 502 errors to /502.html
  error_page   502  /502.html;
  location = /502.html {
    root   /usr/share/nginx/html;
  }
  
  # redirect other server error to the static page /50x.html
  error_page   500 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }
}

Configuring PHP-FPM as Upstream Server

Now that NGINX is installed, you must set up PHP-FPM. You don’t want incoming requests from your NGINX server to be a mess, so you need an upstream server to handle requests properly.

1. Log in to the appserver, open PHP-FPM’s configuration file (/etc/php-fpm.d/www.conf) in your text editor, and add the following directives.

These directives allow PHP-FPM to serve requests from wbserver only on port 9000 with default configuration settings

[www]
user = nginx
listen = 9000
listen.allowed_clients = 192.168.8.171
listen.acl_users = apache,nginx
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

2. Create a new file named hello.php in the /usr/share/nginx/html/ directory, and add the following line. This hello.php page will be requested throughout this tutorial to confirm that the fixes have taken effect.

<?php echo "Hello from ATA"; ?>

3. Next, run the systemctl enable command below to set up php-fpm as a service –now, and enable the service to start at bootup.

sudo systemctl enable --now php-fpm
Enabling the PHP-FPM service
Enabling the PHP-FPM service

If you get errors while trying to start the service, double-check the configuration file for typos.

4. Ultimately, execute the following command, which doesn’t provide output but appends (>>) the IP address of wbserver to the hosts file (/etc/hosts) for local DNS resolution.

sudo bash -c "echo '192.168.8.171 wbserver' >> /etc/hosts"

Fixing the Unavailable Upstream Server 502 Error

All the pieces are in place, and you’re almost ready to investigate and fix your first 502 error. But first, you’ll create a scenario where the upstream server is unavailable due to a crash or power cycle.

1. Execute the shutdown command below on appserver to turn off the machine immediately (now) to mimic an unavailable server.

sudo shutdown now

2. Next, log in to wbserver and navigate to http://wbserver/hello.php in the test web browser. You’ll be greeted with a 502 error, as shown below.

Displaying a 502 Error
Displaying a 502 Error

3. Run the below tail command to view the last (-n) five (5) lines of error.log to investigate the cause of the error.

sudo tail -n 5 /var/log/nginx/error.log

You’ll see error log entries containing the text connect() failed (113:No route to Host) while connecting to upstream, as shown below.

This log message indicates that the issue lies in the connection to the upstream node, not in NGINX itself.

Viewing the NGINX error log

4. Lastly, turn the upstream server (appserver) back on to fix the 502 error.

Refresh the browser page in wbserver to confirm the issue has been fixed, as shown below.

Confirming the 502 error is fixed
Confirming the 502 error is fixed

Ensuring PHP-FPM is Running in the Upstream Server

Another common cause of NGINX 502 errors is when the PHP-FPM service is down on a reachable server. For this tutorial, you’ll kill the PHP-FPM process to replicate a 502 error and how to fix the error.

1. Log in to appserver, and execute the pkill command, which doesn’t provide output, but kills all PHP-related services.

sudo pkill php

2. Next, navigate to the hello.php page in wbserver, and you’ll get a 502 error in your test browser, as shown below.

Encountering a 502 error
Encountering a 502 error

3. Run the systemctl command below to confirm the status of the php-fpm service.

sudo systemctl status php-fpm.service

Below, you’ll notice that the PHP-FPM service is inactive and has 0 active processes.

This status is the result of when you manually killed the underlying processes. But the service may crash and die in the wild for several reasons.

Confirming the status of PHP-FPM
Confirming the status of PHP-FPM

4. Now, execute the systemctl status command again to display more information about the stopped php-fpm service.

sudo systemctl status php-fpm.service

Pay attention to the log section of the output below. If errors affect the start or continuous running of the service, deal with those errors.

Viewing Systemctl PHP-FPM error log
Viewing Systemctl PHP-FPM error log

Check the default log file(/var/log/php-fpm/error.log) for further pointers about why the service cannot start.

5. Run the systemctl start command, which doesn’t have an output, but starts the php-fpm service.

sudo systemctl start php-fpm.service

6. Next, rerun the systemctl status command to confirm the state of the php-fpm service.

sudo systemctl status php-fpm.service

As you can see below, the PHP-FPM service is now active (running).

Displaying the status of PHP-FPM
Displaying the status of PHP-FPM

7. Finally, reload your test browser page in wbserver to confirm the 502 error is resolved, as shown below.

Confirming the 502 Error is resolved
Confirming the 502 Error is resolved

Modifying Firewall Rules to Fix NGINX 502 Errors

A properly configured and running NGINX and PHP-FPM services is not all you need to dodge NGINX 502 errors. A misconfigured firewall can also be a source of 502 errors.

To see how you can fix this error, you’ll first recreate a firewall-caused 502 error condition:

1. Run the firewall-cmd command below to show the firewall’s state. Fedora 35 uses firewall-cmd as a command-line interface for its firewall solution, Firewalld.

firewall-cmd --state

By default, on a Fedora system, the firewall is running, as shown below.

Checking Firewalld running state
Checking Firewalld running state

2. Next, execute the below firewall-cmd command to remove access to port 9000 over Transmission Control Protocol (TCP).

Blocking port 9000 makes PHP-FPM inaccessible to external machines, including the NGINX host, wbserver.

sudo firewall-cmd --remove-port 9000/tcp
Blocking external access to PHP-FPM
Blocking external access to PHP-FPM

3. Refresh your test browser page. Once again, you’ll get a 502 error, as shown below.

Encountering a 502 error
Encountering a 502 error

4. Now, run the following firewall-cmd command to add port 9000 to the list of allowed ports over TCP.

sudo firewall-cmd --add-port 9000/tcp

You should receive a success notification as in the screenshot below.

Allowing access to PHP-FPM through the Firewall
Allowing access to PHP-FPM through the Firewall

5. Run the firewall-cmd command to make the current runtime configuration permanent. Doing so prevents further 502 errors caused by blocked firewall ports, especially after reboots.

sudo firewall-cmd --runtime-to-permanent

The output below indicates the 502 error has been fixed. But you can never be too sure, right?

Making the firewall configuration permanent
Making the firewall configuration permanent

6. Lastly, reload the test browser page in wbserver to confirm the issue has been resolved, as shown below.

Confirming the 502 error caused by blocked ports is fixed
Confirming the 502 error caused by blocked ports is fixed

Changing DNS Resolution Target for the Upstream Server

By now, all should be working fine, but what will you do if you get another 502 error? An error in DNS resolution can also cause NGINX 502 errors.

To fix a DNS-caused NGINX 502 error:

1. Log in to the NGINX host machine (wbserver).

2. Edit the hosts file (/etc/hosts) in your text editor.

sudo vi /etc/hosts

3. Change the IP address for the PHP-FPM server (appserver) to an incorrect IP.

Choose an IP that is not assigned to any machine, save the changes and close the editor. This tutorial uses the IP address 192.168.8.156.

Editing the hosts file
Editing the hosts file

4. Now, refresh the test web page (http://wbserver/hello.php).

As shown below, you’ll get the 502 error since PHP-FPM is not listening at 192.168.8.156.

Encountering a DNS-caused 502 error
Encountering a DNS-caused 502 error

5. Run nslookup to view the result of DNS resolution for the domain name appserver.

nslookup appserver

As expected, DNS queries for appserver return the wrong IP address, as shown below.

Displaying DNS resolution for appserver
Displaying DNS resolution for appserver

6. Edit the hosts file on wbserver with your text editor, and put the correct IP address for the appserver.

This step varies depending on how you’re performing DNS resolution. This tutorial uses local hosts files, so this step suffices.

Editing the Hosts file
Editing the Hosts file

In a typical enterprise setting, DNS resolution is provided by Active Directory or a hosting provider. Whatever the case, NGINX expects to be directed to a socket on the PHP-FPM server when it has to deal with PHP requests.

Talk to your DNS administrator (if that’s not you). For NGINX hosted on servers on the internet, you might have to look at your hosting provider’s CPANEL or similar tool.

7. Rerun the nslookup command to confirm the fix has taken effect.

Displaying DNS resolution for appserver
Displaying DNS resolution for appserver

8. Ultimately, refresh your test browser page in wbserver to confirm the issue has been resolved.

Below, you can see that you’re no longer getting 502 errors.

Confirming DNS-caused 502 errors are fixed
Confirming DNS-caused 502 errors are fixed

Conclusion

By making it this far, you’ve learned about dealing with 502 errors in an NGINX setup. Whether a service or server is down or a firewall is blocking ports, you can now confidently fix NGINX 502 errors.

This newfound knowledge is just another milestone, so why not check out more NGINX-related tutorials to deepen your skills.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!