Sharepoint CSOM Socket Exception

Solving SocketException when processing List using Sharepoint CSOM

UPDATE (2018-09-05): New additional solution by changing TCP TIME_WAIT delay.

Months ago I’ve made a C# script to synchronize data from external source into a Sharepoint Site using Sharepoint CSOM and PnP. It’s been running just fine until recently it stopped working. I saw the logs and see a lot of SocketException error messages like the one below.

System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted 127.0.0.1:443
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)

So then I did a research and found a stackoverflow.com thread which have a simple explanation by jrista on why it happened.

You are overloading the TCP/IP stack. Windows (and I think all socket stacks actually) have a limitation on the number of sockets that can be opened in rapid sequence due to how sockets get closed under normal operation.

Whenever a socket is closed, it enters the TIME_WAIT state for a certain time (240 seconds IIRC).

Each time you poll, a socket is consumed out of the default dynamic range (I think its about 5000 dynamic ports just above 1024), and each time that poll ends, that particular socket goes into TIME_WAIT.

If you poll frequently enough, you will eventually consume all of the available ports, which will result in TCP error 10048.

Then I did a crosscheck with the article I found from Microsoft (see references below), it turns out Windows Server has 5000 port limitation by default.

New Entry! I’ve written a new solution using C# code without changing any value from registry. This will be useful when you have some restrictions on server computer configuration.

Solution #1: Change Dynamic Port Range

The fix is very simple, at least for now. You only need to edit / create a certain key in Registry.

To do that, open run and type regedit. Go to following path of registry key.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

Create (or edit if already exist) MaxUserPort key with DWORD value type. The valid range for this value is 5000-65534 (decimal). If the key doesn’t exist, the value is set to 5000 automatically. In my case, I set it to maximum value 65534 and it works just fine.

The C# script is running again without problems. Now let’s see how long this solution can hold.

Solution #2: Change TCP Timed Wait Delay

If you still see problems using previous solution, you can also change TCP TIME_WAIT delay through TcpTimedWaitDelay registry key.

The TcpTimedWaitDelay value determines the length of time that a connection stays in the TIME_WAIT state when being closed. While a connection is in the TIME_WAIT state, the socket pair can’t be reused.

Similar with previous solution, you can do it by opening run and type regedit. Go to following path of registry key.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

Create (or edit if already exist) TcpTimedWaitDelay key with DWORD value type. The valid range for this value is 30-300 (decimal).

The default value is 120 (decimal), which means it’ll wait for 120 seconds before the port can be used again. You can change it to lower value so it’ll wait quicker, for example set it to 30 (decimal) so it’ll only wait for 30 seconds.

References