This article can help you troubleshoot issues related to 504/502/gateway errors. When troubleshooting, it can be helpful to understand how the processing works between nginx and PHP, which is often used for high performance web application hosting, like WordPress.
Common errors that occur that are connected to this configuration:
- 504 Gateway Timeout
- Gateway Timeout (504)
- HTTP Error 504 – Gateway Timeout
- Gateway Timeout Error
- 502 bad gateway
- Bad Gateway
Background to gateway errors
Traditional web servers use Apache to respond to HTTP requests, then if there’s a PHP app running (like WordPress), they’ll interact with PHP directly like this:
Apache -> php-fastcgi
But over the years apache became bloated, eating up lots of ram and disk IO resources for every single visitor to the site, so web developers decided to build replacement HTTP servers, one such server being nginx. We use it to ensures the websites we host are responding as quickly as possible.
Adding nginx to the mix results in the above changing to look like this:
nginx -> apache -> php-fpm
nginx acts as a gateway sending requests through to apache and PHP. If there’s a problem ‘downstream’ — such as with apache or php — you often get a gateway error, like 502 Bad Gateway or 504 Gateway Timeout.
Troubleshooting Gateway Errors
One simple ‘cover-all’ solution is to directly restart the underlying services. If you don’t have root access to the server, then you can often trigger such a restart by making changes to your website configuration in Plesk.
For example, try going to the “PHP Settings” button for your domain, then making any small change there (like increasing memory from 32MB to 35MB) then save your changes. This update triggers a restart of apache and PHP processing and could solve your error!
It may take up to 1 minute (or longer depending on your provider) for the changes to take effect as there may be a specific web server restart interval configured on your server. We rarely configure our restart interval to be longer than 1 minute.
Check the logs to see what’s being reported. sometimes the logs will simply report a 502 error — just like you’re seeing in the browser, which won’t be all that helpful. But sometimes the error log will pinpoint what plugin or theme is causing the error. You can learn how to use Plesk to view logs here.
Cause: External Resources
The PHP script is looping or trying to communicate with an external resource that’s taking so long as to reach its timeout, then when it fails to execute properly, it returns to nginx saying “sorry, couldn’t do it” to which nginx will provide a gateway error, like bad gateway (502) or gateway timeout (504).
To solve issues with External Resources, you’ll need to look into what parts of your software are trying to retrieve external resources, like connections to Google Fonts, or the Twitter API. Similarly, any services that require connectivity on a non-standard port (standard ports are 80 and 443) will require that we open a hole in the firewall to allow the connection through. An example of this is certain payment gateways, or XML API services.
If you’re using WordPress or any other CMS with plugins, be sure to try disabling any plugin that might communicate externally to see if it solves the problem. If you can narrow down which part of the software could be doing this, then we can work on a solution together, like using an alternate plugin, or perhaps opening a port in the firewall if that’s what’s required.
Cause: Limited Buffers
Nginx is configured to not provide enough wiggle room to PHP, such as with too small buffers. Here’s how to configure nginx’s buffers.
Cause: PHP Processes running for long time
Sometimes if you’re getting constant Gateway Timeout errors, and the only thing that clears them up is restarting PHP (as described above), or if you’re on a VPS and you see your PHP processes staying running at high CPU and lasting far longer than they should, you may need to take some steps to rein them in. Here are some options that have worked for us:
- PHP-FPM allows you to tune the PHP Process Manager (FastCGI Process Manager = FPM) by making some changes in Plesk. If you’re using the “ondemand” style PHP-FPM process, you may want to reduce the number of requests each process handles before gracefully exiting / restarting a new process. This is labelled as pm.max_requests. Try 100 or 150 if you’re having performance issues
- If your PHP processes aren’t dying off, you may need to *make* them die. There’s a couple good ways to do this. First is to definitely set an idle timeout for the PHP-FPM processes by setting pm.process_idle_timeout – try setting it to 10s (you can do this in the field below the FPM settings.
- If your PHP processes still aren’t dying off, you may need to get even more aggressive with them. Try setting request_terminate_timeout to a few seconds higher than your max_execution_time setting. If max_execution_time doesn’t kill off the process, request_terminate_timeout certainly will.
Cause: Too many PHP Processes needed to serve requests
If your site requires a lot of php processes due to a large amount of traffic creating dynamic processing requests, the first thing to check is that you have caching enabled. If you’re using WordPress see here to learn how to do this. There’s also tips in there about how to reduce dynamic processing.
If you’re unable to access your website administration panel, you can either block access to the particular part of the site that’s eating up resources, or you can block access to all IPs except your own to regain access (at least temporarily). Here’s how:
To block access to the highly requested resource: use the logs (as indicated above) to identified the particular PHP file that’s being requested repeatedly. Then can add the following code snippet to the top of your .htaccess file to block the highly requested resource (even just temporarily) so you can access the admin panel. Replace filename\.php with the actual filename. If there are dots in the path be sure to prepend them with a backslash as seen in the example.
<FilesMatch filename\.php> Order Allow,Deny Deny from all </FilesMatch>
To block access to all IPs except your own: in Plesk visit the apache & nginx settings page. Under “Deny access to the site” enter a custom value and make it
"*“ (without the quotes). Then under “Excluding” enter your own IP address. Be sure to remove this when you’re done troubleshooting.