Christie
Christie

Reputation: 113

"Resource temporarily unavailable" error from System.Net.Sockets

I am working on a .NET API that runs inside of a docker container. At some point it makes a call to a Python Flask API that is also running in a container.

var response = await httpClient.GetAsync("http://service-name:8000/actual/url")

which then produces the following error:

System.Net.Http.HttpRequestException: Resource temporarily unavailable
---> System.Net.Sockets.SocketException (11): Resource temporarily unavailable
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken 
cancellationToken)

Has anyone had experience with this before and potentially knows a solution? I cant find much on the web about it at all. I have some seen some mentions of the issue potentially being related to the Flask API not using async methods but that doesnt make sense to me.

The Flask API produces the appropriate responses when accessed through a web browser or Postman using localhost:8000/actual/url and the container logs these responses. I have tried using the localhost URL in the .NET API but that does not work either.

If anymore information is needed please leave a comment and I will do my best to update the post quickly.

-- Christie

Upvotes: 7

Views: 22981

Answers (3)

我零0七
我零0七

Reputation: 493

You can use nslookup service-name command check DNS server response.

If get connection timed out; no servers could be reached error.

You may change DNS setting for the host.

Upvotes: 0

Chris G
Chris G

Reputation: 21

Just in case anyone ends up here 8 years later, I just had this issue when debugging on Visual Studio with WSL2 running dotnet core. Kept getting this error with little to no information about why. I believe it was my Company hiding the DNS information on the host so that the WSL instance didn't properly inherit the DNS. I changed it to googles publicly available one and it worked right away. linux i think its /etc/resolv.conf

Hope this helps someone

Upvotes: 2

Alex N
Alex N

Reputation: 325

TLDR

A reason for the "Resource temporarily unavailable" error is when during name resolution the DNS Server responds with RCODE 2 (Server failure).

Long answer

I noticed the same behavior in a dotnet application running in a dotnet runtime alpine docker container. Here are the results of my investigation:

The error message "Resource temporarily unavailable" corresponds to the EAGAIN error code which gets returned by various functions from the C standard library. At first I suspected the connect() function because the C# stack trace indicates the error happening during the ConnectAsync() call of the c# socket. And indeed the EAGAIN error code appears in the man page of connect() with this description: "No more free local ports or insufficient entries in the routing cache".

I simulated a system with depleted local ports and noticed that a different exception gets thrown in that case, which rules out local port availability as a root cause for the original exception. Regarding the other mentioned cause in the man page it turns out that the routing cache was removed from Linux in 2012. commit

I started to look around for EAGAIN in the source of the musl C lib which is used in the dotnet runtime alpine docker container. After a while I finally noticed the gethostbyname2_r function which is used for resolving a domain name to an ip address via DNS. During System.Net.Sockets.Socket.ConnectAsync() the hostname is still a string and the name resolving happens in native code using the gethostbyname2_r function (or one of its variations).

The final question is: When does gethostbyname2_r return the EAGAIN error code? It's when the RCODE field in the header of the DNS Response has the value 2, which stands for "Server failure". source line 166

To verify this result I ran a simple mock DNS server which always returns the RCODE 2 in the DNS response. The resulting c# exception along with the stack trace matched the original exception exactly.

Upvotes: 16

Related Questions