Error Medic

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.

Last updated:
Last verified:
2,089 words
Key Takeaways
  • 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
Fix Approaches Compared
MethodWhen to UseTime to ApplyRisk
Restart service (systemctl restart apache2)Temporary relief after crash; confirms service can start< 1 minLow — brief downtime
apachectl configtest + reloadSyntax errors causing startup failure; safe config changes1–5 minVery low — no downtime if reload
Tune MaxRequestWorkers + ServerLimitOOM crashes, too many connections, memory exhaustion5–15 minMedium — requires restart
Switch MPM (prefork → event)High concurrency with PHP-FPM; reducing memory per worker15–30 minMedium — requires module swap and restart
Analyze core dump with gdbSegfault crashes, unknown crashes with no log evidence30–60 minNone — read-only analysis
Disable suspect moduleModule-triggered segfaults at startup or under load5–10 minMedium — may break dependent features
Increase swap / add RAMPersistent OOM on under-provisioned servers10–30 minLow — 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:

  1. OOM kill — the Linux kernel terminates Apache workers to reclaim memory
  2. Port binding failure — another process holds port 80 or 443 at startup
  3. Configuration syntax error — a bad VirtualHost or SSLCertificateFile path prevents Apache from loading
  4. Segfault in a module — a third-party .so (mod_php, mod_security) corrupts memory
  5. 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 kernel
  • Main PID: 1234 (code=dumped, signal=SEGV) → segmentation fault, core dump generated
  • AH00016: Configuration Failed → syntax error, check apachectl -t
  • (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80 → port conflict
  • AH00485: 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

bash
#!/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 ==="
E

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

Related Articles in Apache

Explore More Linux Sysadmin Guides