Introduction
When PHP-FPM is restarted or reloaded, Apache connections to PHP-FPM via mod_proxy_fcgi can fail with "Connection refused" errors. This happens because the PHP-FPM socket file may be removed and recreated during restart, or TCP connections are dropped before Apache's connection pool notices. The error log shows:
[Tue Apr 09 00:15:00.123456 2026] [proxy:error] [pid 5678] (111)Connection refused: AH00957: FCGI: attempt to connect to Unix domain socket /run/php/php8.2-fpm.sock failedSymptoms
- 503 Service Unavailable for all PHP pages immediately after PHP-FPM restart
- Apache error log shows "Connection refused" to PHP-FPM socket
- Error lasts from a few seconds to several minutes after PHP-FPM restart
- Static files serve correctly; only PHP requests fail
- Socket file exists at the expected path but Apache cannot connect
Common Causes
- PHP-FPM socket file is removed before the new one is created during restart
- Apache's connection pool still holds references to the old (deleted) socket
- PHP-FPM pool starts listening on a different socket path after configuration change
- TCP backlog queue overflow when many Apache connections attempt to reconnect simultaneously
- PHP-FPM process takes time to initialize pools before accepting connections
Step-by-Step Fix
- 1.Configure PHP-FPM socket with proper permissions. Edit
/etc/php/8.2/fpm/pool.d/www.conf: - 2.```ini
- 3.listen = /run/php/php8.2-fpm.sock
- 4.listen.owner = www-data
- 5.listen.group = www-data
- 6.listen.mode = 0660
- 7.
` - 8.Ensure the socket directory exists and is writable:
- 9.```bash
- 10.sudo mkdir -p /run/php
- 11.sudo chown www-data:www-data /run/php
- 12.
` - 13.Use TCP instead of Unix socket for more resilient connections during restarts:
- 14.In PHP-FPM pool config:
- 15.```ini
- 16.listen = 127.0.0.1:9000
- 17.
` - 18.In Apache VirtualHost:
- 19.```apache
- 20.<FilesMatch \.php$>
- 21.SetHandler "proxy:fcgi://127.0.0.1:9000"
- 22.</FilesMatch>
- 23.
` - 24.TCP connections handle restart scenarios more gracefully than Unix sockets.
- 25.Configure Apache proxy retry behavior:
- 26.```apache
- 27.<Proxy "fcgi://127.0.0.1:9000">
- 28.ProxySet retry=5
- 29.</Proxy>
- 30.
` - 31.Or for Unix socket:
- 32.```apache
- 33.<FilesMatch \.php$>
- 34.SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost/"
- 35.</FilesMatch>
- 36.
` - 37.Implement graceful PHP-FPM reload instead of restart:
- 38.```bash
- 39.# Use reload instead of restart - this waits for in-flight requests
- 40.sudo systemctl reload php8.2-fpm
# Or send USR2 signal for graceful reload sudo kill -USR2 $(cat /run/php/php8.2-fpm.pid) ```
- 1.Add a health check wrapper for PHP-FPM restarts:
- 2.```bash
- 3.#!/bin/bash
- 4.sudo systemctl reload php8.2-fpm
- 5.for i in {1..10}; do
- 6.if curl -sf http://localhost/health.php > /dev/null; then
- 7.echo "PHP-FPM is healthy"
- 8.exit 0
- 9.fi
- 10.echo "Waiting for PHP-FPM... attempt $i"
- 11.sleep 1
- 12.done
- 13.echo "PHP-FPM failed to become healthy"
- 14.exit 1
- 15.
`
Prevention
- Always use
systemctl reloadinstead ofsystemctl restartfor PHP-FPM to avoid dropping the socket - Monitor PHP-FPM pool status via the status page: enable
pm.status_path = /fpm-status - Use TCP connections (
127.0.0.1:9000) instead of Unix sockets in high-availability setups - Add PHP-FPM health monitoring:
systemctl status php8.2-fpm && curl -sf http://localhost/health.php - Keep PHP-FPM
pm.start_servershigh enough to handle connection bursts after restart - Deploy PHP-FPM configuration changes during low-traffic windows with proper rollback procedures