Apache Crash & Not Working: Complete Troubleshooting Guide (Connection Refused, OOM, Core Dump)
Fix Apache crashes, connection refused errors, and OOM kills in minutes. Step-by-step diagnostic commands, MPM tuning, and core dump analysis included.
- Apache crashes most often from memory exhaustion (OOM killer) when MaxRequestWorkers is set too high relative to available RAM — calculate (Total RAM - OS overhead) / memory-per-worker before adjusting
- Connection refused on port 80/443 almost always means Apache either failed to bind the port (another process owns it) or the service itself exited — check `ss -tlnp | grep :80` and `systemctl status apache2` immediately
- A core dump at startup usually points to a broken module (.so) or corrupted MPM configuration — run `apachectl -t` and check `/var/log/apache2/error.log` for the offending module line
- Apache 'too many connections' errors are almost always a KeepAliveTimeout misconfiguration holding idle workers — lowering it from the default 5s to 2s often resolves saturation under load
- When Apache is slow rather than fully crashed, suspect DNS reverse lookups (HostnameLookups On), runaway CGI processes, or disk I/O wait caused by access logs on a full filesystem
| Method | When to Use | Time to Apply | Risk |
|---|---|---|---|
| Restart service (systemctl restart apache2) | Temporary relief after crash; confirms service can start | < 1 min | Low — brief downtime |
| apachectl configtest + reload | Syntax errors causing startup failure; safe config changes | 1–5 min | Very low — no downtime if reload |
| Tune MaxRequestWorkers + ServerLimit | OOM crashes, too many connections, memory exhaustion | 5–15 min | Medium — requires restart |
| Switch MPM (prefork → event) | High concurrency with PHP-FPM; reducing memory per worker | 15–30 min | Medium — requires module swap and restart |
| Analyze core dump with gdb | Segfault crashes, unknown crashes with no log evidence | 30–60 min | None — read-only analysis |
| Disable suspect module | Module-triggered segfaults at startup or under load | 5–10 min | Medium — may break dependent features |
| Increase swap / add RAM | Persistent OOM on under-provisioned servers | 10–30 min | Low — swap addition is online |
Understanding Apache Crashes and Failures
Apache HTTP Server (apache2 on Debian/Ubuntu, httpd on RHEL/CentOS) is a multi-process/multi-threaded daemon managed by a parent process that spawns workers. When the parent or a worker dies unexpectedly, symptoms range from a full service outage (apache crash, apache not working) to intermittent apache connection refused errors during high traffic. Because workers are forked from the parent, a single misconfigured module or a memory cliff can take down every active connection simultaneously.
The five most common root causes are:
- OOM kill — the Linux kernel terminates Apache workers to reclaim memory
- Port binding failure — another process holds port 80 or 443 at startup
- Configuration syntax error — a bad VirtualHost or SSLCertificateFile path prevents Apache from loading
- Segfault in a module — a third-party
.so(mod_php, mod_security) corrupts memory - Worker pool exhaustion — all workers are occupied, new connections are refused at the TCP layer
Step 1: Identify the Failure Mode
Check service status and last journal entries first:
systemctl status apache2 # Debian/Ubuntu
systemctl status httpd # RHEL/CentOS/Fedora
journalctl -u apache2 -n 100 --no-pager
Look for one of these patterns in the output:
Main PID: 1234 (code=killed, signal=KILL)→ OOM kill by kernelMain PID: 1234 (code=dumped, signal=SEGV)→ segmentation fault, core dump generatedAH00016: Configuration Failed→ syntax error, checkapachectl -t(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80→ port conflictAH00485: scoreboard is full, not at MaxRequestWorkers→ worker pool saturated
Check the Apache error log directly:
tail -n 200 /var/log/apache2/error.log # Debian/Ubuntu
tail -n 200 /var/log/httpd/error_log # RHEL/CentOS
Step 2: Fix OOM Crashes (apache out of memory)
The Linux OOM killer logs to /var/log/kern.log or the kernel ring buffer:
dmesg | grep -i 'oom\|killed process\|apache\|httpd' | tail -30
grep -i 'oom\|out of memory' /var/log/kern.log | tail -20
You will see lines like:
Out of memory: Kill process 4521 (apache2) score 312 or sacrifice child
Killed process 4521 (apache2) total-vm:1048576kB, anon-rss:524288kB
Calculate the correct MaxRequestWorkers:
# Check current memory per worker
ps -ylC apache2 --sort:rss | awk 'NR>1{sum+=$8; count++} END{print "Avg RSS:", sum/count/1024, "MB; Count:", count}'
# Get available RAM (exclude OS overhead ~256MB)
free -m | awk '/Mem/{print ($2 - 256) " MB available for Apache"}'
Then set in /etc/apache2/mods-enabled/mpm_prefork.conf (or equivalent):
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 50 # (available_RAM_MB / avg_worker_MB)
ServerLimit 50
MaxConnectionsPerChild 1000
</IfModule>
After editing: apachectl configtest && systemctl reload apache2
Step 3: Fix Connection Refused (apache connection refused)
If Apache is not running:
systemctl start apache2
systemctl status apache2 # look for the failure reason
If Apache is running but still refusing connections:
# Confirm what's listening on port 80
ss -tlnp | grep ':80'
lsof -i :80
# Test locally to isolate network vs Apache
curl -v http://127.0.0.1/
If another process owns port 80 (nginx, another Apache instance):
# Identify the conflicting process
ss -tlnp | grep ':80' | awk '{print $NF}'
# Output example: users:(("nginx",pid=1122,fd=6))
systemctl stop nginx # or reconfigure ports
Step 4: Fix apache service not starting (Configuration Errors)
Always validate before starting:
apachectl -t # syntax check
apachectl -t -D DUMP_VHOSTS # list all virtual hosts as Apache sees them
apachectl -t -D DUMP_MODULES # list loaded modules
Common errors and their fixes:
| Error Message | Cause | Fix |
|---|---|---|
AH00526: Syntax error on line 45 |
Typo in config file | Edit the reported file and line |
AH02572: No SSL Certificate configured |
Missing SSLCertificateFile | Point to correct .pem path |
AH00534: apache2: Configuration error: No MPM loaded |
MPM module disabled | a2enmod mpm_event && systemctl restart apache2 |
Invalid command 'Header' |
mod_headers not loaded | a2enmod headers |
Step 5: Analyze apache core dump (Segfault Debugging)
Enable core dumps and locate them:
# Check if core dumps are being generated
ulimit -c # should not be 0
cat /proc/sys/kernel/core_pattern
# Common locations
ls -lh /var/crash/
ls -lh /tmp/core*
ls -lh /etc/apache2/core*
coredumpctl list # on systemd systems
Analyze with gdb:
apt-get install -y apache2-dbg gdb # install debug symbols
# Load the core dump
gdb /usr/sbin/apache2 /var/crash/core.1234
# Inside gdb:
(gdb) bt full # full backtrace
(gdb) info threads # check all threads
(gdb) thread apply all bt # backtrace for every thread
A backtrace pointing to mod_php, mod_security2, or a third-party module:
# Temporarily disable the suspect module
a2dismod php8.1
a2dismod security2
apachectl configtest && systemctl restart apache2
Step 6: Fix apache too many connections / apache slow
Tune KeepAlive for high-traffic servers:
# /etc/apache2/apache2.conf
KeepAlive On
KeepAliveTimeout 2 # reduce from default 5
MaxKeepAliveRequests 100
Identify slow requests in real time:
# Enable mod_status
a2enmod status
# Add to a VirtualHost or .htaccess:
# <Location /server-status>
# SetHandler server-status
# Require ip 127.0.0.1
# </Location>
curl http://127.0.0.1/server-status?refresh=5
# Find long-running requests
watch -n2 'curl -s http://127.0.0.1/server-status | grep -E "(W|_|R|C|D|K)\s+[0-9]+\s+[0-9]+\s+[0-9]+" | head -20'
Disable reverse DNS lookups (major performance killer):
HostnameLookups Off # ensure this is Off, not On
Check for a full filesystem causing apache slow / apache failed log writes:
df -h
lsof | grep deleted | grep apache # large deleted-but-open log files
Step 7: Prevent Future Crashes
Set up automatic restart and memory alerting:
# Systemd restart policy
systemctl edit apache2
# Add:
# [Service]
# Restart=on-failure
# RestartSec=5s
# MemoryMax=2G
# Monitor with a simple cron health check
echo '*/5 * * * * root curl -sf http://127.0.0.1/ > /dev/null || systemctl restart apache2' > /etc/cron.d/apache-watchdog
Enable Apache crash log rotation to prevent log files consuming all disk space:
cat /etc/logrotate.d/apache2 # verify rotation is configured
apachectl -t && logrotate -f /etc/logrotate.d/apache2
Frequently Asked Questions
#!/usr/bin/env bash
# Apache Crash Diagnostic Script
# Run as root: bash apache-diag.sh
set -euo pipefail
APACHE_SVC="apache2"
ERROR_LOG="/var/log/apache2/error.log"
[[ -f /etc/redhat-release ]] && APACHE_SVC="httpd" && ERROR_LOG="/var/log/httpd/error_log"
echo "=== 1. SERVICE STATUS ==="
systemctl status "${APACHE_SVC}" --no-pager -l | head -30
echo ""
echo "=== 2. LAST 50 ERROR LOG LINES ==="
tail -n 50 "${ERROR_LOG}" 2>/dev/null || echo "Log not found: ${ERROR_LOG}"
echo ""
echo "=== 3. KERNEL OOM / SEGFAULT EVENTS (last 24h) ==="
dmesg --since '24 hours ago' 2>/dev/null | grep -iE 'oom|kill|apache|httpd|segfault' | tail -20 || \
grep -iE 'oom|killed|apache|httpd' /var/log/kern.log 2>/dev/null | tail -20 || \
echo "No kernel events found (may need root or journalctl -k)"
echo ""
echo "=== 4. PORT 80 / 443 LISTENERS ==="
ss -tlnp | grep -E ':80|:443' || echo "Nothing listening on 80/443"
echo ""
echo "=== 5. MEMORY USAGE ==="
free -h
echo ""
echo "--- Apache worker memory ---"
ps -ylC "${APACHE_SVC}" --sort:rss 2>/dev/null | awk 'NR==1{print} NR>1{sum+=$8; count++; print} END{if(count>0) printf "\nTotal workers: %d | Avg RSS: %.1f MB | Total RSS: %.1f MB\n", count, sum/count/1024, sum/1024}' || echo "No apache processes found"
echo ""
echo "=== 6. CONFIG SYNTAX CHECK ==="
apachectl -t 2>&1
echo ""
echo "=== 7. LOADED MODULES ==="
apachectl -M 2>/dev/null | grep -v '^Loaded' | sort
echo ""
echo "=== 8. CORE DUMPS ==="
coredumpctl list 2>/dev/null | grep -iE 'apache|httpd' | tail -10 || \
ls -lh /var/crash/core* /tmp/core* 2>/dev/null || \
echo "No core dumps found in standard locations"
echo ""
echo "=== 9. DISK SPACE (log partitions) ==="
df -h "$(dirname ${ERROR_LOG})" /
echo ""
echo "=== 10. RECENT SYSTEMD JOURNAL ==="
journalctl -u "${APACHE_SVC}" --since '2 hours ago' --no-pager | tail -40
echo ""
echo "=== DIAGNOSTIC COMPLETE ==="
Error Medic Editorial
The Error Medic Editorial team consists of senior Linux systems engineers and SREs with combined experience managing Apache, Nginx, and application servers at scale across cloud and on-premise environments. Our guides are tested against real production failure scenarios on Debian, Ubuntu, RHEL, and CentOS systems.
Sources
- https://httpd.apache.org/docs/2.4/mpm.html
- https://httpd.apache.org/docs/2.4/mod/mpm_common.html#maxrequestworkers
- https://httpd.apache.org/docs/2.4/mod/core.html#keepalivetimeout
- https://www.kernel.org/doc/html/latest/admin-guide/mm/oom_kill.html
- https://httpd.apache.org/docs/2.4/programs/apachectl.html
- https://stackoverflow.com/questions/tagged/apache?tab=Frequent
- https://github.com/apache/httpd/issues