Detecting ephemeral port exhaustion
Symptoms
When Windows or Windows Server is out of ephemeral/outbound/dynamic network ports, it will not be able to establish any outbound network connections. This results in a lot of connection failures such as database and/or domain controller connections. If the system is not responding, then try increasing the port range (discussed below) - this change is effective immediately. If the system immediately recovers, then you know you are dealing with this issue. You can either increase the port range which may just delay the problem or you can try to identify the cause.
Detecting user mode port leaks
Ephemeral ports are range of ports that Windows and Windows Server use for outbound communications over the TCP/IP network protocol. When an outbound connection is finished, the port associated to the connection is put into a TIMED_WAIT state for two minutes by default. This allows any lingering packets on the network to be ignored. Windows Server 2008 and later use the IANA range which uses the ports between 49152 and 65535 providing 16,383 ports.
Some applications and services such as Microsoft Exchange Server CAS servers can be very “chatty” and might actually use all 16,383 ports within a two minute time period. The result is connection failures similar to “Couldn’t connect to X, due to no ports available from the end point mapper”.
If you suspect ephemeral port exhaustion, then consider running the following Powershell script called “Log-EphemeralPortStats.ps1” at
https://1drv.ms/f/s!AhuJirRUDDbmkotkPocbTrN0wgKB7Q
Warning: This script is provided as sample code only. Please review it and use at your own risk.
Be aware that this only detects user mode port leaks. If a driver (kernel mode) is leaking ports, then a complete memory dump must be sent to Microsoft Support for analysis to know which driver is responsible. The memory dump must be taken when the system has leaked a significant number of ports.
This script is designed to run in an infinite loop of 1 minute sleep intervals and write to a log file called “EphemeralPortStats.log”. Here is an example of the output it produces:
Computer DateTime LocalAddress #OfEPortsInUse Max#OfEPorts %EPortUsage #OfTcpListeningPorts #OfPids
-------- -------- ------------ -------------- ------------ ----------- -------------------- -------
ETCHEDCHAMPION 8/9/2013 12:37:42 PM 127.0.0.1 6 16384 0 15 11
ETCHEDCHAMPION 8/9/2013 12:37:42 PM 172.18.96.192 3 16384 0 15 10
ETCHEDCHAMPION 8/9/2013 12:37:42 PM 192.168.1.2 69 16384 0.4 15 17
This script is intended to be ran from the console of the computer suspected to be running low on ephemeral ports and to leave it running. Periodically review the log to see if there was any ephemeral port exhaustion detected.
This script gets the port range from:
netsh int ipv4 show dynamicportrange tcp
Then, correlates this information with the output of:
netstat –ano –p tcp
PsExec can be potentially used to get this information from remote computers, but keep in mind that passwords used in PsExec are sent in the clear over the network.
My PFE colleagues and customers have used this script quit a bit and I hope it will help you as well.
Also, as a temporary work-around, the ephemeral/dynamic/outbound port range can be increased using the following command:
netsh int ipv4 set dynamicport tcp start=10000 num=55535
This change takes affect immediately. No need to restart. No need to reboot. This is about three times larger than the default. If this change has a positive affect when the problem occurs, then you know that this is the issue your system is dealing with.
To set the port range back to default, use the following command:
netsh int ipv4 set dynamicport tcp start=49152 num=16384
To check the port range:
netsh int ipv4 show dynamicportrange tcp
Once you have identify the process consuming the ports, contact the developer of the process for a fix.
Also, consider decreasing the TIMED WAIT delay using the TcpTimedWaitDelay registry key.
Detecting kernel mode port leaks
All of the above covers user mode port leaks - meaning leaks originating from processes. If a driver (kernel mode) leaks a port, then netstat will not be able to report it. Kernel mode port leaks can only be detected by inducing a complete memory dump and then analyzing the dump with the MEX debug extension. Load MEX into WinDBG and then run the following commands to help identify ports associated with drivers.
!mex.afd -conn -report -verbose
!afd -endp -report
!tcpip -p
Once you identify the driver consumer the ports, contact the developer of the driver.
If you suspect a Windows Server 2008 R2 system might be running out of ephemeral ports, then apply the following hotfix:
Kernel sockets leak on a multiprocessor computer that is running Windows Server 2008 R2 or Windows 7
https://support.microsoft.com/en-us/kb/2577795
Windows Server 2012 and later are already patched with this fix.
UPDATE
Windows 10 and Windows Server 2012 R2 introduced the "q" parameter in netstat. This parameter displays all connections, listening ports, and bound non-listening TCP ports. Bound non-listening ports may or may not be associated with an active connection.
Comments
Anonymous
January 01, 2003
Ah, it must be 4 minutes. My memory must be failing. I was thinking of TcpTimedWaitDelay at technet.microsoft.com/.../cc938217.aspx. It says 4 minutes.Anonymous
January 01, 2003
Thank you for the useful information.Anonymous
August 12, 2013
Two minutes or four minutes? I thought four minutes as that is 2xMSL, with each MSL being 120 seconds (2 minutes). TechNet says 4 minutes as well.Anonymous
August 11, 2014
Thanks Client awesome script. Very useful. Should be somewhere in Windows monitored or an Event log if running out of ports.
Can you put it to http://gallery.technet.microsoft.com/scriptcenter/site/upload as well please. ThanksAnonymous
February 13, 2015
So what next? How to troubleshoot this? Owner of process is SystemAnonymous
March 02, 2015
To Clint Huffman - Can you please provide the powershell script source code as cannot download from the link provided -https://skydrive.live.com/redir?resid=E6360C54B48A891B!5328Anonymous
March 04, 2015
Hi Clint: Good article. Can you please provide the powershell script source sode as cannot download from the link provided.Anonymous
March 30, 2015
Thanks for the script. Should this list the actual detail of ports in use or just the number of ports? i.e. if ports start to get exhausted will we need to then run 'netstat -ano -p tcp' to get the detail?
This is generally happening out of hours so we would not be on the console to check. By the time we do the ports are fine again.Anonymous
May 15, 2015
Hi Clint,
i've taken the liberty of adapting your script to list the number of ephemeral ports in ESTBLISHED, TIME_WAIT and SYN_RECEIVED states, and also listing the top 5 PIDs, with process name and number of ports assigned. any suggestions as to what i can do with it? do you have a listing on the script repository i could append it to?- Anonymous
September 06, 2016
You can send it directly to me at clinth@microsoft.com and I'll update the script. Thanks! - Anonymous
May 16, 2017
I don't have a repository for this, but you are welcome to publish the script/code anyway you want.
- Anonymous
Anonymous
July 14, 2015
Hi, How do you fix the issue if you have this happening to an Exchange server?- Anonymous
September 06, 2016
By increasing the port range with the following command:netsh int ipv4 set dynamicport tcp start=10000 num=55535
- Anonymous
Anonymous
July 29, 2015
I see a lot of talk on how to detect this, but not how to troubleshoot the underlying cause. In my case it is also local SYSTEM and connecting to SQL. But we do not know which of the many services tools and tasks is behind it, as they are hidden behind system.exe- Anonymous
September 06, 2016
Correct. This blog post only covers user mode port leaks. I'll update it to include kernel mode.
- Anonymous
Anonymous
October 02, 2015
For a quick check of total and used ephemeral ports of a single service (so in my case, a SQL server) do this:
PS C:UsersRack> netsh int ipv4 show dynamicportrange tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384
PS C:UsersRack> netstat -ano | findstr 1433 | measure
Count : 910
Average :
Sum :
Maximum :
Minimum :
Property :
It will only count the MSSQL connections, but in my case those were his only ephemeral. You can also do this with a couple different ports to get numbers you can sum up.Anonymous
March 08, 2016
Do you have the same script working for monitoring UDP port? I tried modifying the script for UDP but not luck.M S Ali- Anonymous
September 06, 2016
The comment has been removed
- Anonymous
Anonymous
March 25, 2016
Once again, thanks Clint! This is exactly what i´m looking for!Anonymous
September 01, 2016
Sorry for the delay. I updated this blog post with a working link to the script.