Panellicense

Fix 502 Bad Gateway on Plesk — nginx, Apache, and PHP-FPM

Diagnose 502 Bad Gateway errors on Plesk from the nginx proxy error log — refused upstreams, saturated PHP-FPM pools, oversized headers, and Apache restarts.

plesk502nginxphp-fpmapachetroubleshooting
schema: HowToschema: FAQPageschema: BreadcrumbList

A 502 on Plesk always means the same thing: nginx, which fronts every site, asked an upstream for a response and didn't get a valid one. The upstream is either Apache (ports 7080/7081) or the domain's PHP-FPM socket, depending on the PHP handler. The fix depends entirely on which upstream failed and why, and the domain's proxy error log tells you both in one line.

This guide is a decision tree keyed on that log line. It covers Plesk Obsidian on AlmaLinux, Rocky, Debian, and Ubuntu. If the 502 comes from the Plesk updater rather than a hosted site, see fixing Plesk update failures instead.

Read the proxy error log first

Every domain has its own nginx error log. Reproduce the 502, then read the last few lines:

tail -n 20 /var/www/vhosts/system/example.com/logs/proxy_error_log

Match the error string against the sections below. If the log is empty, the 502 isn't coming from this server's nginx — check Cloudflare or any load balancer in front of it.

Log containsUpstreamJump to
connect() failed (111: Connection refused) while connecting to upstream + :7081 or :7080Apache downApache is not running
connect() to unix:...php-fpm.sock failed (2: No such file or directory)FPM pool missingPHP-FPM socket missing
connect() to unix:...php-fpm.sock failed (11: Resource temporarily unavailable)FPM saturatedPHP-FPM pool is full
upstream sent too big header while reading response headerEitherResponse headers too large
upstream prematurely closed connection or recv() failed (104: Connection reset by peer)EitherUpstream dies mid-request

A 504 Gateway Time-out with upstream timed out is a different problem — slow PHP, not a broken upstream. Fix the slow script before raising timeouts.

Apache is not running

The domain uses nginx as a proxy and Apache isn't listening. Confirm:

ss -ltnp | grep -E ':708[01]'
systemctl status httpd     # apache2 on Debian/Ubuntu

If nothing listens on 7080/7081, Apache either crashed or failed to start after a config change. Test the config before restarting:

httpd -t                   # apache2ctl -t on Debian/Ubuntu

A syntax error almost always points at a file under /var/www/vhosts/system/<domain>/conf/ — usually a customer's Additional Apache directives with a typo, or a stale include left by a removed extension. Fix or clear the directive in the panel, then rebuild the web server configuration:

plesk sbin httpdmng --reconfigure-domain example.com
systemctl start httpd

If Apache starts but dies again within minutes, check /var/log/httpd/error_log for MaxRequestWorkers or segfault lines. Running out of workers produces refused connections under load, not a crash, so raise the limit only after ruling out a single abusive site.

PHP-FPM socket missing

The domain is on an FPM handler, but the pool's socket doesn't exist. This usually follows a PHP version removal, a failed update, or a domain restored from backup with a handler that isn't installed.

ls -l /var/www/vhosts/system/example.com/php-fpm.sock
systemctl status plesk-php83-fpm

If the service is up but the socket is missing, Plesk didn't write the pool. Re-applying the domain's PHP settings regenerates it — open Domains > example.com > PHP Settings and save without changes, or use the repair utility:

plesk repair web example.com -y

If the PHP version itself is gone, switch the domain to an installed version. Don't reinstall an end-of-life PHP just to bring one site back.

PHP-FPM pool is full

Resource temporarily unavailable means the socket's backlog is full: every child is busy and new connections are being dropped. The FPM log confirms it:

grep max_children /var/log/plesk-php83-fpm/error.log | tail -n 5
WARNING: [pool example.com] server reached pm.max_children setting (5), consider raising it

Plesk's default is pm = ondemand with pm.max_children = 5 per domain. That's fine for a brochure site and too low for WooCommerce with a crawler hitting it. Before raising it, find out why the children are busy:

  • Slow external calls. Payment gateways, license checks, and remote feeds that hang hold a child for their full timeout.
  • Bot traffic on uncached pages. Check the access log for one user-agent or IP range dominating wp-admin/admin-ajax.php or search URLs.
  • A real traffic increase. Then raising the limit is the right fix.

Raise it in PHP Settings > Performance Settings, setting pm.max_children to a value the server's RAM can carry. The sizing math is the same as on cPanel and is covered in PHP-FPM pool tuning. Plesk reloads the pool on save.

Response headers too large

upstream sent too big header means the upstream returned headers bigger than nginx's proxy buffer — usually stacked Set-Cookie headers from a CMS or a security plugin, or a long Link preload header. The default buffer is one memory page (4 KB or 8 KB).

Add to Apache & nginx Settings > Additional nginx directives for the domain. For FPM served by Apache (and any proxied setup):

proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;

For FPM served by nginx, the response doesn't go through proxy_* at all, so use the FastCGI equivalents:

fastcgi_buffer_size 16k;
fastcgi_buffers 8 16k;
fastcgi_busy_buffers_size 32k;

16 KB covers almost every real application. If a site needs more than 64 KB of headers, the application is broken — find the plugin setting cookies in a loop instead of raising buffers further.

Upstream dies mid-request

upstream prematurely closed connection means the upstream accepted the request and then dropped it. Three causes cover nearly every case.

PHP child crashed

Look for segfaults or terminated children around the timestamp of the 502:

grep -E 'SIGSEGV|SIGKILL|request_terminate_timeout' /var/log/plesk-php83-fpm/error.log | tail
dmesg -T | grep -iE 'oom|segfault' | tail

A SIGKILL alongside an OOM message means the kernel killed the child — the server is out of RAM, not the site. A SIGSEGV is almost always a PHP extension: ionCube, a third-party loader, or an outdated imagick. Disable extensions one at a time on that domain to isolate it.

Request killed by a timeout

If request_terminate_timeout or max_execution_time is lower than the time a long import or report takes, PHP kills the child and nginx logs a 502. Run long jobs from cron or WP-CLI instead of the browser, rather than raising timeouts for every request.

Apache restarted under live traffic

If 502s cluster at the same minute every day, or appear right after you create or edit domains, Apache is restarting. Every config change in Plesk triggers an Apache reload, and a full restart drops in-flight requests. Go to Tools & Settings > Apache Web Server, enable graceful restart, and set an Apache restart interval (for example 60 seconds) so bulk changes are batched into one restart.

Prevent repeat 502s

  • Watch proxy_error_log volume per domain with the Plesk Monitoring extension and alert on spikes rather than waiting for tickets.
  • Keep customers off hand-edited Apache directives where possible; one typo stops Apache for every site.
  • Put caching in front of PHP. On high-traffic WordPress subscriptions, LiteSpeed on Plesk with LSCache removes most of the PHP load that fills FPM pools.
What causes 502 Bad Gateway in Plesk?+
nginx, which proxies every Plesk site, didn't get a valid response from Apache or the domain's PHP-FPM socket. The domain's proxy_error_log at /var/www/vhosts/system/<domain>/logs/ names the failing upstream and the reason.
How do I fix 'upstream sent too big header' in Plesk?+
Increase nginx's buffers in the domain's Additional nginx directives. Use proxy_buffer_size and proxy_buffers when PHP goes through Apache, and fastcgi_buffer_size and fastcgi_buffers when FPM is served by nginx. 16k is enough for almost every application.
Why do I get 502 errors when Apache restarts in Plesk?+
A full Apache restart drops in-flight requests, and nginx returns 502 for them. Enable graceful restart and set an Apache restart interval under Tools & Settings > Apache Web Server so config changes are batched.
Where is the nginx error log for a domain in Plesk?+
At /var/www/vhosts/system/example.com/logs/proxy_error_log. Apache's per-domain errors are in error_log in the same directory, and PHP-FPM logs to /var/log/plesk-phpXX-fpm/error.log.
Is a 504 Gateway Timeout the same as a 502 in Plesk?+
No. A 502 means the upstream refused, dropped, or malformed the response. A 504 means it accepted the request but took longer than nginx's timeout, which points at slow PHP or database queries rather than a broken service.

Next steps

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.