title: Random 401 Unauthorized errors using HttpClient
body: <p>I am using HttpClient to invoke a Web Api REST endpoint and once in a while I see a random 401 Unauthorized Status.</p>
  
  <p>Here is my HttpClient wrapper that was created for re usability purposes. I have modified it to keep it simple for this post without modifying the core parts.</p>
  
  <pre><code>public class HttpHelper
  {
          public const string JsonContentType = "application/json";
  
          public T PostAsJsonObject&lt;T&gt;(string uri, T t) where T : class
          {
              using (HttpResponseMessage response = PostJsonHttpRequest(uri, JsonContentType, t))
              {
                  response.EnsureSuccessStatusCode();
                  return response.Content.ReadAsAsync&lt;T&gt;().Result;
              }
          }
  
          private HttpResponseMessage PostJsonHttpRequest&lt;T&gt;(string uri, string contentType, T content) where T : class
          {
              if (String.IsNullOrEmpty(uri))
              {
                  throw new ArgumentNullException("uri");
              }
              HttpResponseMessage response = CreateHttpClient(contentType).PostAsJsonAsync(uri, content).Result;
              return response;
          }
  
          private HttpClient CreateHttpClient(string contentType)
          {
             var credentials = new NetworkCredential("srvuser", "somepwd", "somedomain");
             return new HttpClient(new HttpClientHandler { Credentials = credentials, PreAuthenticate = true });
          }
  }
  </code></pre>
  
  <p>Here is how I am invoking it.</p>
  
  <pre><code>var httpHelper = new HttpHelper();
  var response = httpHelper.PostAsJsonObject("https://xyz.pvt/inventory/api/orders", "234");
  </code></pre>
  
  <p>Most of the time it works fine, but once in a while I get 401 Unauthorized error. I am trying to figure out what might be causing it.</p>
  
  <blockquote>
    <p>System.Net.Http.HttpRequestException: Response status code does not
    indicate success: 401 (Unauthorized).    at
    System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()    at
    HttpHelper.PostAsJsonObject[T](String uri, T t)</p>
  </blockquote>
  
  <p>I looked at asp.net logs, and found a strange pattern. Most of the time, I see pair of entries (401 followed by 200 OK) such as</p>
  
  <pre><code>2017-02-09 12:04:13 104.68.45.152 POST /inventory/api/orders/ - 80 - 132.64.78.120 HTTP/1.1 - 401 2 5 764 
  2017-02-09 12:04:16 104.68.45.152 POST /inventory/api/orders/ - 80 somedomain\srvusr 132.64.78.120 HTTP/1.1 - 200 0 0 2917
  
  2017-02-09 12:04:16 104.68.45.152 POST /inventory/api/orders/ - 80 - 132.64.78.120 HTTP/1.1 - 401 2 5 0 
  2017-02-09 12:04:19 104.68.45.152 POST /inventory/api/orders/ - 80 somedomain\srvusr 132.64.78.120 HTTP/1.1 - 200 0 0 2230
  </code></pre>
  
  <p>But occasionally I just see 401</p>
  
  <pre><code>2017-02-09 12:14:04 104.68.45.152 POST /inventory/api/orders/ - 80 - 132.64.78.120 HTTP/1.1 - 401 2 5 0
  </code></pre>
  
  <p>REST api is implemented using ASP.NET Web Api 2 running on .NET 4.6.1 and in IIS 7.5, it is setup with just Windows Authentication.</p>
  
  <p>Not sure what is causing the authentication to fail once in a while.</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Here is the new code that I wrote using async await pattern.</p>
  
  <pre><code>public class HttpHelper
  {
          public const string JsonContentType = "application/json";
  
          private HttpClient CreateHttpClient(string url, string contentType)
          {
              var handler = new HttpClientHandler
              {
                  Credentials = new CredentialCache { { new Uri(url), "NTLM", new NetworkCredential("srvuser", "somepwd", "somedomain") } },
                  PreAuthenticate = true
              };
              var httpClient = new HttpClient(handler);
              httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
              return httpClient;
          }
  
          private async Task&lt;HttpResponseMessage&gt; PostJsonHttpRequestAsync&lt;T&gt;(string url, string contentType, T content) where T : class
          {
              if (string.IsNullOrEmpty(url))
              {
                  var exception = new ArgumentNullException("url");
                  throw exception;
              }
  
              var response = await CreateHttpClient(url, contentType).PostAsJsonAsync(url, content);
  
              return response;
          }
  
          public async Task&lt;T&gt; PostAsJsonObjectAsync&lt;T&gt;(string uri, T t) where T : class
          {
              using (var response = await PostJsonHttpRequestAsync(uri, JsonContentType, t))
              {
                  return await response.Content.ReadAsAsync&lt;T&gt;(new[]
                      {
                        new JsonMediaTypeFormatter
                        {
                           SerializerSettings = { NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.Auto }
                        }
                      }.AsEnumerable());
              }
          }
      }
  </code></pre>
  
  <p>Here is how I am finally invoking it.</p>
  
  <pre><code>static class TestMe
  {
      static void Main()
      {
          var httpHelper = new HttpHelper();
          var responseTask = httpHelper.PostAsJsonObjectAsync("https://xyz.pvt/inventory/api/orders", "234");
  
          responseTask.Wait(120000);
          var response = responseTask.Result;
          Console.WriteLine(response);
      }
  }
  </code></pre>
  
  <p>Even now I see same problem. Still getting random 401 Unauthorized errors.</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I did some more investigation and found that these mysterious 401 errors are coming from IIS. When ever these mysterious 401 error occurs, IIS log has a corresponding 401 error entry, but in this case the request never reaches asp.net pipeline. As if for some reason the request is bounced back by IIS with 401 error. </p>
  
  <p>Without going into too much in depth, I know that windows authentication in IIS uses 2 requests to manage authentication based on how the HttpClient is configured. So a successful authentication request will have a 401.2 followed by 200 OK. It is what happening most of the time. Occasionally thou I notice there is a 401.2, followed by just 401. The same request upon retry attempt goes thru fine (401.2 followed by 200 OK).</p>
  
  <p>Really appreciate if anyone have some insight into this issue and a potential resolution to it. </p>