System.Net.Sockets.SocketException

A SocketException is thrown when an operation on a network socket fails. It is the exception under most network errors, including the ones you see from HttpClient, SQL connections and message queues, where it is typically the inner exception.

The error code is the most useful part. The SocketErrorCode property gives it as an enum, and the message includes the number, such as (10061).

Minimum version: >= 1.1 >= Core 1.0

Statistics

10
elmah.io logo 6

Common causes

The error code tells you which of these it is. The most common ones are below.

The connection is refused (10061)

The machine was reached, but nothing listens on the port. The service is not running, it listens on another port or address, or a firewall rejects the connection.

using var client = new TcpClient("localhost", 1);   // SocketException (10061): connection refused

Check that the service is running, and the host and port in your configuration. If the service can be down for a moment, retry:

for (var attempt = 1; attempt <= 3; attempt++)
{
    try
    {
        using var client = new TcpClient("localhost", 1);
        break;
    }
    catch (SocketException e) when (e.SocketErrorCode == SocketError.ConnectionRefused && attempt < 3)
    {
        await Task.Delay(TimeSpan.FromMilliseconds(100 * attempt));
    }
    catch (SocketException)
    {
        break;
    }
}

The machine did not answer, so the attempt ended after the timeout of the operating system. A wrong IP address, a machine that is down, or a firewall that drops packets give this error.

Check that the address is correct and that the machine can be reached from where the code runs, with ping or Test-NetConnection. Look at the firewall and network rules for the port.

The name does not resolve. It is misspelled, the DNS server does not know it, or the machine has no network access to the DNS server.

Check the name with nslookup from the same machine, and look for typos in configuration.

The other side closed the connection while you were using it. A server restart, a load balancer that closes idle connections, or a timeout on the server side cause it.

Retry the operation on a new connection. For HTTP, use IHttpClientFactory that renews connections, and keep requests short.

How to fix it and prevent it

Switch on the error code

SocketErrorCode has the cause as an enum. Use it to decide what to do, instead of searching the message.

try
{
    using var client = new TcpClient("localhost", 1);
}
catch (SocketException e)
{
    var advice = e.SocketErrorCode switch
    {
        SocketError.ConnectionRefused => "Nothing is listening on the port.",
        SocketError.TimedOut => "The machine did not answer.",
        SocketError.HostNotFound => "The host name is not known.",
        _ => "Network error: " + e.SocketErrorCode
    };

    Console.WriteLine(advice);
}

Network problems depend on where the code runs. Test from the server or container with the same tools, and not from your own computer: Test-NetConnection host -Port 443 in PowerShell, or curl -v from a shell.

Resets and refused connections are often temporary when a service restarts. Retry a few times with a delay, and limit the attempts so a real outage does not keep requests waiting.

How to read the stack trace

The first line has the error code and the address. The frames show which part of your code opened the connection:

System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it. [::ffff:127.0.0.1]:5001
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
--- End of stack trace from previous location ---
   at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
   at System.Net.Sockets.Socket.Connect(String host, Int32 port)
   at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)
   at System.Net.Sockets.TcpClient..ctor(String hostname, Int32 port)
   at Shop.Services.SocketProbe.Connect(Int32 port) in C:\src\Shop\Services\SocketProbe.cs:line 10
   at Program.<Main>$(String[] args) in C:\src\Shop\Program.cs:line 4

The code is 10061, so the connection was actively refused by 127.0.0.1 on port 5001. The constructor of TcpClient connected on line 10 of SocketProbe.cs. Check that the service runs and that it listens on that address and port.

Should you catch it?

Yes, around code that talks to the network. Use a filter on SocketErrorCode to catch the ones you can handle, and let others pass.

When you use HttpClient, catch HttpRequestException instead. The SocketException is its InnerException.

Find SocketException before your users do

elmah.io logs every unhandled exception in your .NET application with its stack trace and request details, groups identical errors and notifies you when a new one appears.

Start free trial
Free 21-day trial No credit card required

Related exceptions

Frequently asked questions

What does error 10061 mean?

The connection was refused. The machine is reachable, but no process accepts connections on that port. Check that the service runs and that the port is right.

10061 is an answer: the machine says no. 10060 is no answer at all, so the attempt timed out, often because of a firewall or a wrong address.

The server has other network rules, DNS, proxies and firewalls. Test the connection from the server with the same host and port.

Read e.SocketErrorCode for the enum, or e.ErrorCode for the number from the operating system.

Let your AI agent track it down

Connect Claude Code, Cursor, VS Code or Visual Studio to the elmah.io MCP server and ask your agent to look into SocketException for you. For example:

AI chat
Find the most frequent SocketException in my production log and show me the line that throws it.

The agent reads the stack trace and request details from elmah.io, finds the code in your repository and proposes a fix. In Claude Code, add the server with one command:

claude mcp add --transport http --client-id claudecode elmahio https://mcp.elmah.io/mcp

The MCP server is included on every plan and is currently in beta. Set up the MCP server.

Further reading

YouTube videos

Answers from Stack Overflow

As you may be aware, if a host receives a packet for a UDP port that is not currently bound, it may send back an ICMP "Port Unreachable" message. Whether or not it does this is dependent on the firewall, private/public settings, etc. On localhost, however, it will pretty much always send this packet back.

In your server code, you are calling SendAsync to old clients, which prompts these "port unreachable" messages.

Now, on Windows (and only on Windows), by default, a received ICMP Port Unreachable message will close the UDP socket that sent it; hence, the next time you try to receive on the socket, it will throw an exception because the socket has been closed by the OS.

Obviously, this causes a headache in the multi-client, single-server socket set-up you have here, but luckily there is a fix:

You need to utilise the not-often-required SIO_UDP_CONNRESET Winsock control code, which turns off this built-in behaviour of automatically closing the socket.

I don't believe this ioctl code is available in the dotnet IoControlCodes type, but you can define it yourself. If you put the following code at the top of your server repro, the error no longer gets raised.

const uint IOC_IN = 0x80000000U;
const uint IOC_VENDOR = 0x18000000U;

/// <summary>
/// Controls whether UDP PORT_UNREACHABLE messages are reported. 
/// </summary>
const int SIO_UDP_CONNRESET = unchecked((int)(IOC_IN | IOC_VENDOR | 12));

var udpClient = new UdpClient(9001);
udpClient.Client.IOControl(SIO_UDP_CONNRESET, new byte[] { 0x00 }, null);

Note that this ioctl code is only supported on Windows (XP and later), not on Linux, since it is provided by the Winsock extensions. Of course, since the described behavior is only the default behavior on Windows, this omission is not a major loss. If you are attempting to create a cross-platform library, you should cordon this off as Windows-specific code.

By Alistair Evans. Read the original answer on Stack Overflow.

On Windows Vista (and Windows 7), Dns.GetHostEntry also returns IPv6 addresses. In your case, the IPv6 address (::1) is first in the list.

You cannot connect to an IPv6 (InterNetworkV6) address with an IPv4 (InterNetwork) socket.

Change your code to create the socket to use the address family of the specified IP address:

Socket serverSocket =
    new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                        ↑

Note: There's a shortcut to obtain the IP address of localhost: You can simply use IPAddress.Loopback (127.0.0.1) or IPAddress.IPv6Loopback (::1).

By dtb. Read the original answer on Stack Overflow.

An established connection was aborted by the software in your host machine

That is a boiler-plate error message, it comes out of Windows. The underlying error code is WSAECONNABORTED. Which really doesn't mean more than "connection was aborted". You have to be a bit careful about the "your host machine" part of the phrase. In the vast majority of Windows application programs, it is indeed the host that the desktop app is connected to that aborted the connection. Usually a server somewhere else.

The roles are reversed however when you implement your own server. Now you need to read the error message as "aborted by the application at the other end of the wire". Which is of course not uncommon when you implement a server, client programs that use your server are not unlikely to abort a connection for whatever reason. It can mean that a fire-wall or a proxy terminated the connection but that's not very likely since they typically would not allow the connection to be established in the first place.

You don't really know why a connection was aborted unless you have insight what is going on at the other end of the wire. That's of course hard to come by. If your server is reachable through the Internet then don't discount the possibility that you are being probed by a port scanner. Or your customers, looking for a game cheat.

By Hans Passant. Read the original answer on Stack Overflow.

Is it possible that the serverSocket is being closed from another thread? That will cause this exception.

By TimK. Read the original answer on Stack Overflow.

You just need to keep digging. The exception "The response ended prematurely" isn't the root cause. Keep digging into the inner exceptions until you find the last one. You'll find this:

System.IO.IOException: Authentication failed because the remote party has closed the transport stream.

So it's not about your code. It seems the server you're hitting either can't handle the load, or is intentionally dropping your requests because you're hitting it too hard.

By Gabriel Luci. Read the original answer on Stack Overflow.