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.
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
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.
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 IP address of wbserver to the hosts file (/etc/hosts) for local DNS resolution.
- 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
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.
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.
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.
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.
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.
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.
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).
7. Finally, reload your test browser page in wbserver to confirm the 502 error is resolved, as shown below.
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.
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
3. Refresh your test browser page. Once again, you’ll get a 502 error, as shown below.
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.
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?
6. Lastly, reload the test browser page in wbserver to confirm the issue has been resolved, as shown below.
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.
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.
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.
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.
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.
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.
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.