In TCP/IP networking, LAST_ACK
is one of the possible states shown in netstat
output. It indicates that a connection is in the final stage of termination, where one endpoint has sent a FIN packet and received an ACK for it, but is still waiting for the remote endpoint's FIN packet to complete the connection teardown.
When a Windows server shows thousands of connections in LAST_ACK
state, it typically indicates one of these scenarios:
- The remote client crashed or disconnected improperly without completing the TCP handshake
- Network issues preventing the final ACK from reaching your server
- Application bugs where sockets aren't being properly closed
- Resource exhaustion preventing proper connection cleanup
Here's a PowerShell script to analyze LAST_ACK
connections:
# Get all TCP connections in LAST_ACK state
$lastAckConnections = Get-NetTCPConnection -State LastAck
# Group by remote address to find problematic clients
$lastAckConnections | Group-Object RemoteAddress | Sort-Object Count -Descending
# Check if specific ports are affected
$lastAckConnections | Group-Object LocalPort | Sort-Object Count -Descending
Based on the diagnosis, consider these approaches:
# Adjust TCP timeout settings (requires admin)
Set-NetTCPSetting -SettingName InternetCustom -InitialRtoMs 3000
Set-NetTCPSetting -SettingName InternetCustom -MaxSynRetransmissions 2
# For application-level issues, implement proper socket cleanup:
try {
$socket = New-Object System.Net.Sockets.TcpClient
# ... socket operations ...
} finally {
if ($socket -ne $null) {
$socket.Close()
$socket.Dispose()
}
}
Implement regular monitoring with this Nagios check:
#!/bin/bash
LAST_ACK_COUNT=$(netstat -an | grep -c "LAST_ACK")
WARNING=100
CRITICAL=500
if [ "$LAST_ACK_COUNT" -ge "$CRITICAL" ]; then
echo "CRITICAL: $LAST_ACK_COUNT connections in LAST_ACK"
exit 2
elif [ "$LAST_ACK_COUNT" -ge "$WARNING" ]; then
echo "WARNING: $LAST_ACK_COUNT connections in LAST_ACK"
exit 1
else
echo "OK: $LAST_ACK_COUNT connections in LAST_ACK"
exit 0
fi
For persistent issues, consider these registry modifications:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"TcpTimedWaitDelay"=dword:0000001e
"MaxUserPort"=dword:0000fffe
"TcpNumConnections"=dword:00fffffe
In TCP protocol terminology, LAST_ACK
represents the final acknowledgment state in the connection termination sequence. When a connection enters this state, one endpoint has sent a FIN (finish) packet and received an ACK (acknowledgment) for it, and is now waiting for the remote endpoint's FIN packet before fully closing.
// Typical TCP state transition during connection termination
CLOSE_WAIT → LAST_ACK → CLOSED
When a Windows server shows numerous connections stuck in LAST_ACK
, several scenarios could be at play:
- The remote client failed to properly close the connection (didn't send FIN)
- Network issues preventing FIN packets from reaching the server
- Application bugs where processes aren't properly closing sockets
- OS-level TCP stack issues or configuration problems
First, verify the state with netstat:
netstat -ano | findstr LAST_ACK
# Count occurrences:
netstat -ano | find /c "LAST_ACK"
Check associated processes:
tasklist /FI "PID eq [process_id_from_netstat]"
Immediate mitigation:
# Reset lingering connections (Windows Server 2012+)
netsh int ip reset
# Or adjust TCP timeout (temporary)
netsh int tcp set global rto=1000
Permanent fixes:
- Update network drivers and Windows patches
- Review application socket handling code
- Adjust TCP stack parameters in registry
This C# example shows correct socket termination:
try {
// Normal shutdown sequence
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch (Exception ex) {
// Force closure if normal shutdown fails
socket.Dispose();
}
finally {
if (socket != null)
socket.Dispose();
}
Use Performance Monitor to track TCP connections:
Counter: TCPv4/Connections
Instance: _Total
Consider implementing connection health checks in your applications and setting appropriate keepalive timeouts.