Apache 2.4 Service Freeze on Windows Server: Troubleshooting Unkillable httpd.exe Processes and Service Termination Failures


2 views

When attempting to stop Apache 2.4 services on Windows Server (both 2008 R2 and 2012 R2), we encounter a situation where:

httpd.exe

becomes completely resistant to termination through normal means. The service appears stuck in "Stopping" state indefinitely in Services Manager.

Standard Windows process termination methods fail:

taskkill /im "httpd.exe" /f /t
:: Returns ERROR: The process with PID X could not be terminated

Even Sysinternals tools report false positives:

pskill -t PID
:: Claims process killed while it remains active

The issue began manifesting after these July 2018 patches:

  • KB4338420 (Security Monthly Quality Rollup)
  • KB4338818 (Security Only Update)
  • KB4339093 (Servicing Stack Update)
  • KB4338423 (IE Cumulative Update)

When the service gets stuck, try this sequence:

sc queryex Apache2.4
sc stop Apache2.4 /force
taskkill /f /fi "MODULES eq httpd.exe"
net stop Apache2.4 /y

Option 1: Downgrade problematic updates (test environment first):

wusa /uninstall /kb:4338420 /quiet /norestart

Option 2: Implement pre-stop cleanup in Apache configuration:

# In httpd.conf
AcceptFilter http none
EnableSendfile Off
Win32DisableAcceptEx

html

Recently, multiple Windows Server administrators have reported a peculiar issue where Apache HTTP Server 2.4.x (specifically builds from Apache Haus) becomes completely resistant to termination. The service appears in a "stopping" state indefinitely, while child processes remain active but unresponsive to termination commands.

When attempting to stop Apache 2.4.27+ on Windows Server 2008 R2/2012 R2, we observe:

  • Service Control Manager shows "Stopping" state permanently
  • httpd.exe processes remain in memory but become ghost processes
  • Standard termination methods fail with misleading errors

Command attempts and their outputs:

# Using taskkill
taskkill /im "httpd.exe" /f /t
ERROR: The process with PID 560 (child process of PID 480) could not be terminated.
Reason: There is no running instance of the task.

# Using Sysinternals pskill
pskill -t 560
Process 5956 killed. # False positive - process remains

This behavior emerged after July 2018 Windows Updates (KB4338420, KB4338818, KB4339093, KB4338423). The most probable culprit is a security update modifying process handling in Windows Server. Key findings:

  • Affects Apache 2.4.x in reverse-proxy configurations
  • Occurs when ProxyPass/ProxyPassReverse directives are active
  • Process handles become invalid while the process remains resident

Before resorting to server reboots, try these methods:

# Method 1: Complete process tree termination
@echo off
for /f "tokens=2" %%i in ('tasklist ^| findstr httpd.exe') do (
   wmic process where (processid^=%%i) delete
)

# Method 2: Service restart via SC command
sc query Apache2.4 | find "STATE" | find "RUNNING" && (
   sc stop Apache2.4
   timeout /t 30
   sc start Apache2.4
)

For long-term stability:

  1. Update Strategy:
    • Upgrade to Apache 2.4.46+ with modified service control logic
    • Apply Windows Server cumulative update KB5005039 (2021 fix)
  2. Configuration Adjustments:
    # httpd.conf modifications
    AcceptFilter http none
    AcceptFilter https none
    EnableSendfile Off
    EnableMMAP Off
  3. Service Wrapper Replacement:

    Consider replacing Apache's default service wrapper with NSSM (Non-Sucking Service Manager):

    nssm install Apache2.4 "C:\Apache24\bin\httpd.exe" -k runservice
    nssm set Apache2.4 AppStopMethodSkip 6
    nssm set Apache2.4 AppStopMethodConsole 1500

Implement these PowerShell scripts for proactive monitoring:

# Process state checker
while($true) {
   $apache = Get-Process httpd -ErrorAction SilentlyContinue
   if($apache -and $apache.Responding -eq $false) {
      Stop-Process -Id $apache.Id -Force
      Restart-Service Apache2.4
   }
   Start-Sleep -Seconds 60
}

# Service watchdog
Add-Type -AssemblyName System.ServiceProcess
$service = New-Object System.ServiceProcess.ServiceController("Apache2.4")
if($service.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Stopped) {
   $service.Start()
}

Remember to test these solutions in staging environments before production deployment. The issue appears particularly sensitive to certain proxy configurations and Windows Server update combinations.