# Fix Apache PHP-FPM Proxy Connection Refused Pool Error

Your Apache server configured with mod_proxy_fcgi to proxy PHP requests to PHP-FPM starts returning 503 errors. The error log shows:

bash
[Thu Apr 08 09:45:12.345678 2026] [proxy:error] [pid 3456] (111)Connection refused: AH00957: FCGI: attempt to connect to 127.0.0.1:9000 (*) failed
[Thu Apr 08 09:45:12.345679 2026] [proxy_fcgi:error] [pid 3456] AH01079: failed to make connection to backend: 127.0.0.1
[Thu Apr 08 09:45:12.345680 2026] [proxy:error] [pid 3457] AH00959: ap_proxy_connect_backend disabling worker for (127.0.0.1) for 60s

Apache cannot connect to the PHP-FPM pool. The connection is refused, meaning nothing is listening on the expected address and port.

Step 1: Verify PHP-FPM Is Running

bash
sudo systemctl status php8.2-fpm
sudo systemctl is-active php8.2-fpm

If PHP-FPM is not running, start it and check why it stopped:

bash
sudo systemctl start php8.2-fpm
sudo journalctl -u php8.2-fpm --since "10 minutes ago" --no-pager

Common reasons PHP-FPM stops: configuration syntax error in a pool file, missing PHP extensions, or the PHP-FPM process running out of memory.

Step 2: Check Pool Listen Address

PHP-FPM pools can listen on TCP sockets or Unix sockets. Verify what your pool is configured to use:

bash
grep -r "listen\s*=" /etc/php/8.2/fpm/pool.d/

You will see something like:

bash
/etc/php/8.2/fpm/pool.d/www.conf:listen = /run/php/php8.2-fpm.sock

or:

bash
/etc/php/8.2/fpm/pool.d/www.conf:listen = 127.0.0.1:9000

If PHP-FPM listens on a Unix socket but Apache is configured for TCP (or vice versa), the connection fails.

Step 3: Match Apache Configuration to PHP-FPM

For Unix Socket

apache
<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>

For TCP Socket

apache
<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

The Apache handler must exactly match the PHP-FPM listen directive. A common mistake after upgrading PHP is that the socket path changes (e.g., from php8.1-fpm.sock to php8.2-fpm.sock) but the Apache configuration is not updated.

Step 4: Check Socket Permissions

If using Unix sockets, the Apache user must be able to access the socket file:

bash
ls -la /run/php/php8.2-fpm.sock
# Expected: srw-rw---- 1 www-data www-data

If the socket is owned by a different user, update the pool configuration:

bash
; In /etc/php/8.2/fpm/pool.d/www.conf
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Then restart PHP-FPM:

bash
sudo systemctl restart php8.2-fpm

Step 5: Check PHP-FPM Pool Capacity

Even if PHP-FPM is running, it may be unable to accept new connections because all workers are busy:

bash
# Check pool status via the status page
curl -s http://127.0.0.1/fpm-status

Look for listen queue -- if this number is consistently high and max children reached is non-zero, PHP-FPM is overloaded:

bash
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
bash
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 500

Step 6: PHP-FPM Process Manager Type

The process manager type affects how PHP-FPM handles load:

bash
pm = dynamic

vs:

bash
pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s

ondemand starts workers only when needed, conserving memory on low-traffic servers. dynamic maintains a pool of idle workers, reducing response latency during traffic spikes. For production servers with consistent traffic, dynamic is preferred. For development or low-traffic servers, ondemand saves resources.

Testing the Connection

```bash # Test TCP connection nc -zv 127.0.0.1 9000

# Test Unix socket curl -s --unix-socket /run/php/php8.2-fpm.sock http://localhost/fpm-status ```

After fixing the configuration, test with a PHP file:

bash
echo "<?php phpinfo();" | sudo tee /var/www/html/test.php
curl -s http://localhost/test.php | grep -c "PHP Version"
# Should return 1 if PHP is working through Apache