title: The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available
body: <p>We are intermittently getting a <code>The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available</code> exception in our WebApi endpoint.</p>
  
  <p>Does anyone know what is causing this error, or how it can be reproduced in a consistent way? Currently it happens in 150 out of 100,000 requests.</p>
  
  <p>The exception is thrown by <code>XmlDeserialize()</code> in this part of the code:</p>
  
  <pre><code>[HttpPost]
  public async Task&lt;IHttpActionResult&gt; Process()
  {
      using (var requestStream = await Request.Content.ReadAsStreamAsync())
      {
          XmlSerializer serializer = new XmlSerializer(typeof(MyEntity));
  
          // !! The below line throws the exception
          MyEntity entity = serializer.Deserialize(requestStream) as MyEntity;
      }
      ...
  }
  </code></pre>
  
  <p>This is the full exception message:</p>
  
  <pre><code>  "ExceptionType": "HttpException",
    "Message": "The client is disconnected because the underlying request has been completed.  There is no longer an HttpContext available.",
    "StackTrace": [
      "HttpBufferlessInputStream.Read;0",
      "SeekableBufferedRequestStream.Read;0",
      "XmlTextReaderImpl.ReadData;0",
      ...
  </code></pre>
  
  <hr>
  
  <p><strong>Edit:</strong> I found this in the source code for .NET.
  <a href="https://github.com/microsoft/referencesource/blob/master/System.Web/System.Web.txt" rel="noreferrer">System.Web.txt</a>:</p>
  
  <pre><code>HttpBufferlessInputStream_ClientDisconnected=The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available.
  </code></pre>
  
  <p><a href="https://referencesource.microsoft.com/#system.web/HttpBufferlessInputStream.cs,332ecbede7a1f12a" rel="noreferrer">https://referencesource.microsoft.com/#system.web/HttpBufferlessInputStream.cs,332ecbede7a1f12a</a>:</p>
  
  <pre><code>// We are done if the count == 0 or there is no more content
  while (count &gt; 0 &amp;&amp; _remainingBytes != 0) {
      // Do the actual read
      bytesRead = wr.ReadEntityBody(buffer, offset, count);
      if (bytesRead &lt;= 0) {
          if (!_context.Response.IsClientConnected) {
              if (_persistEntityBody) {
                  SetRawContentOnce();
              }
              throw new HttpException(SR.GetString(SR.HttpBufferlessInputStream_ClientDisconnected));
  </code></pre>
  
  <p>So the exception is thrown by HttpBufferlessInputStream.Read(), after <code>wr.ReadEntityBody(buffer, offset, count)</code> returns 0 or negative, and  <code>_context.Response.IsClientConnected</code> is false.</p>
  
  <p>This would mean that the client became disconnected while XmlDeserialize() was still running. But from my limited experiments with netcat, .NET waits until the entire XML request has been uploaded before even calling the controller method. So we aren't uploading the request while we are still deserializing.</p>