System.Net.WebException: The remote name could not be resolved:

Poul K. Sørensen picture Poul K. Sørensen · Jul 29, 2014 · Viewed 157.6k times · Source

I am testing an endpoint that I am experiencing some issues with.

I am simply using HttpClient in a loop that performs a request each hour.

var httpClient = new HttpClient();
var message = httpClient.GetAsync(url).Result;
Console.WriteLine(message.StatusCode);

Once in a while I am getting this exception:

System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The remote name could not be resolved: 'xxx'

The experience is that right after the exception, the URL can be accessed. In a browser you simply refresh the page and all is good.

I still haven't got any reports from users experiencing it so I am wondering if it's just a local issue here but could use a little information to help diagnose.

Is there a way to check if The remote name could not be resolved is caused by an DNS issue or by a web server issue from the exceptions? Can I get more information out of HttpCLient or do I need more advanced diagnostic tools?

Answer

Adriano Repetti picture Adriano Repetti · Jul 29, 2014

It's probably caused by a local network connectivity issue (but also a DNS error is possible). Unfortunately HResult is generic, however you can determine the exact issue catching HttpRequestException and then inspecting InnerException: if it's a WebException then you can check the WebException.Status property, for example WebExceptionStatus.NameResolutionFailure should indicate a DNS resolution problem.


It may happen, there isn't much you can do.

What I'd suggest to always wrap that (network related) code in a loop with a try/catch block (as also suggested here for other fallible operations). Handle known exceptions, wait a little (say 1000 msec) and try again (for say 3 times). Only if failed all times then you can quit/report an error to your users. Very raw example like this:

private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;

public static async Task<HttpResponseMessage> GetFromUrlAsync(string url) {
    using (var client = new HttpClient()) {
        for (int i=1; i <= NumberOfRetries; ++i) {
            try {
                return await client.GetAsync(url); 
            }
            catch (Exception e) when (i < NumberOfRetries) {
                await Task.Delay(DelayOnRetry);
            }
        }
    }
}