title: SocketException (10054) while using .NET 5 only when large request is sent
body: <p>I am migrating my WCF client from .NET Framework 4.6.1 to .NET 5 and I am facing SocketException every time I am sending big requests (like 500KB). Below you can find exception, Server config, .NET Framework config and .NET 5 config.</p>
  <p><strong>Exception:</strong></p>
  <pre><code>System.ServiceModel.CommunicationException: Error while copying content to a stream.
   ---&gt; System.Net.Http.HttpRequestException: Error while copying content to a stream.
   ---&gt; System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host..
   ---&gt; System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
     --- End of inner exception stack trace ---
     at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
     at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
     at System.Net.Security.SslStream.&lt;WriteSingleChunk&gt;g__CompleteWriteAsync|177_1[TIOAdapter](ValueTask writeTask, Byte[] bufferToReturn)
     at System.Net.Security.SslStream.WriteAsyncChunked[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
     at System.Net.Security.SslStream.WriteAsyncInternal[TIOAdapter](TIOAdapter writeAdapter, ReadOnlyMemory`1 buffer)
     at System.Net.Http.HttpConnection.WriteAsync(ReadOnlyMemory`1 source, Boolean async)
     at System.ServiceModel.Channels.BufferedMessageContent.SerializeToStreamAsync(Stream stream, TransportContext context)
     at System.Net.Http.HttpContent.&lt;CopyToAsync&gt;g__WaitAsync|56_0(ValueTask copyTask)
     --- End of inner exception stack trace ---
     at System.Net.Http.HttpContent.&lt;CopyToAsync&gt;g__WaitAsync|56_0(ValueTask copyTask)
     at System.Net.Http.HttpConnection.SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.HttpConnection.SendRequestContentWithExpect100ContinueAsync(HttpRequestMessage request, Task`1 allowExpect100ToContinueTask, HttpContentWriteStream stream, Timer expect100Timer, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, Boolean async, ICredentials credentials, Boolean isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken)
     at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
     at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, Boolean async, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken)
     at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
     at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
     at System.ServiceModel.Channels.HttpChannelFactory`1.HttpClientRequestChannel.HttpClientChannelAsyncRequest.SendRequestAsync(Message message, TimeoutHelper timeoutHelper)
     --- End of inner exception stack trace ---
     at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
     at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
     at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
     at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.&lt;&gt;c__DisplayClass1_0.&lt;CreateGenericTask&gt;b__0(IAsyncResult asyncResult)
  --- End of stack trace from previous location ---
     at EQ.SP.SOS.Adapter.Application.Services.AlertsService.GetUnreadAlertsAsync() in C:\Repozytoria\ShareholderPlatform\APP\EQ.SP.SOS.Adapter\EQ.SP.SOS.Adapter.Application\Services\AlertsService.cs:line 53
     at EQ.SP.SOS.Adapter.API.Controllers.AlertsController.GetUnreadAlerts() in C:\Repozytoria\ShareholderPlatform\APP\EQ.SP.SOS.Adapter\EQ.SP.SOS.Adapter.API\Controllers\AlertsController.cs:line 26
     at lambda_method537(Closure , Object )
     at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.&lt;InvokeActionMethodAsync&gt;g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.&lt;InvokeNextActionFilterAsync&gt;g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State&amp; next, Scope&amp; scope, Object&amp; state, Boolean&amp; isCompleted)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.&lt;InvokeInnerFilterAsync&gt;g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.&lt;InvokeFilterPipelineAsync&gt;g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
     at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.&lt;InvokeAsync&gt;g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
     at Microsoft.AspNetCore.Routing.EndpointMiddleware.&lt;Invoke&gt;g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
     at EQ.SP.SOS.Adapter.API.Middleware.RequestTransferAgentMiddleware.Invoke(HttpContext context, ITransferAgentContext transferAgentContext) in C:\Repozytoria\ShareholderPlatform\APP\EQ.SP.SOS.Adapter\EQ.SP.SOS.Adapter.API\Middleware\RequestTransferAgentMiddleware.cs:line 22
     at EQ.SP.SOS.Adapter.API.Middleware.RequestMetaDataMiddleware.Invoke(HttpContext context, IMetaDataContext metadataContext, IConfiguration config) in C:\Repozytoria\ShareholderPlatform\APP\EQ.SP.SOS.Adapter\EQ.SP.SOS.Adapter.API\Middleware\RequestMetaDataMiddleware.cs:line 22
     at EQ.SP.SOS.Adapter.API.Middleware.RequestUserDataMiddleware.Invoke(HttpContext context, IUserDataContext userDataContext, IConfiguration config) in C:\Repozytoria\ShareholderPlatform\APP\EQ.SP.SOS.Adapter\EQ.SP.SOS.Adapter.API\Middleware\RequestUserMiddleware.cs:line 24
     at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
     at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
  </code></pre>
  <p><strong>Server config:</strong></p>
  <pre><code>&lt;wsHttpBinding&gt;
      &lt;binding name=&quot;wsbinding&quot; closeTimeout=&quot;10:01:00&quot; openTimeout=&quot;10:01:00&quot; receiveTimeout=&quot;10:10:00&quot; sendTimeout=&quot;10:01:00&quot; bypassProxyOnLocal=&quot;false&quot; transactionFlow=&quot;false&quot; hostNameComparisonMode=&quot;StrongWildcard&quot; maxBufferPoolSize=&quot;2147483647&quot; maxReceivedMessageSize=&quot;2147483647&quot; messageEncoding=&quot;Text&quot; textEncoding=&quot;utf-8&quot; useDefaultWebProxy=&quot;false&quot; allowCookies=&quot;false&quot;&gt;
          &lt;readerQuotas maxDepth=&quot;2147483647&quot; maxStringContentLength=&quot;2147483647&quot; maxArrayLength=&quot;2147483647&quot; maxBytesPerRead=&quot;2147483647&quot; maxNameTableCharCount=&quot;2147483647&quot; /&gt;
          &lt;security mode=&quot;Transport&quot;&gt;
              &lt;transport clientCredentialType=&quot;Certificate&quot; /&gt;
          &lt;/security&gt;
      &lt;/binding&gt;
  &lt;wsHttpBinding&gt;
  .NET Framework 4.6.1 client config:
  
  &lt;wsHttpBinding&gt;
      &lt;binding name=&quot;wsbinding&quot; closeTimeout=&quot;00:10:00&quot; openTimeout=&quot;00:10:00&quot; receiveTimeout=&quot;00:10:00&quot; sendTimeout=&quot;00:10:00&quot; bypassProxyOnLocal=&quot;false&quot; transactionFlow=&quot;false&quot; hostNameComparisonMode=&quot;StrongWildcard&quot; maxBufferPoolSize=&quot;2147483647&quot; maxReceivedMessageSize=&quot;2147483647&quot; messageEncoding=&quot;Text&quot; textEncoding=&quot;utf-8&quot; useDefaultWebProxy=&quot;true&quot; allowCookies=&quot;false&quot;&gt;
          &lt;readerQuotas maxDepth=&quot;2147483647&quot; maxStringContentLength=&quot;2147483647&quot; maxArrayLength=&quot;2147483647&quot; maxBytesPerRead=&quot;2147483647&quot; maxNameTableCharCount=&quot;2147483647&quot; /&gt;
          &lt;reliableSession ordered=&quot;true&quot; inactivityTimeout=&quot;00:10:00&quot; enabled=&quot;false&quot; /&gt;
          &lt;security mode=&quot;Transport&quot;&gt;
              &lt;transport clientCredentialType=&quot;Certificate&quot; /&gt;
          &lt;/security&gt;
      &lt;/binding&gt;
  &lt;/wsHttpBinding&gt;
  </code></pre>
  <p><strong>.NET 5 client config:</strong></p>
  <pre><code>private static void RegisterWcfClient&lt;TIService, TClient&gt;(this IServiceCollection services, string baseUrl,
      string serviceName, string certName, string storeLocation)
      where TIService : class
      where TClient : ClientBase&lt;TIService&gt;, new()
  {
  
      services.AddScoped(servicesCollection =&gt;
      {
  
          var client = new TClient();
          var customBinding = new CustomBinding();
  
          var httpsBindingElement = new HttpsTransportBindingElement
          {
              AllowCookies = true,
              MaxBufferSize = int.MaxValue,
              MaxReceivedMessageSize = int.MaxValue,
              RequireClientCertificate = true
          };
  
          customBinding.Elements.Add(httpsBindingElement);
  
          client.Endpoint.Binding = customBinding;
          client.Endpoint.Address = new EndpointAddress($&quot;{baseUrl}/{serviceName}&quot;);
  
          var storeLocationEnum = ToStoreLocationEnum(storeLocation);
          client.ClientCredentials.ClientCertificate.SetCertificate(storeLocationEnum, StoreName.My,
              X509FindType.FindBySubjectName, certName);
  
          return client;
      });
  
      services.AddScoped(servicesCollection =&gt;
      {
          var factory = servicesCollection.GetService&lt;TClient&gt;()?.ChannelFactory;
          return factory.CreateChannel();
      });
  }
  </code></pre>
  <p><strong>.NET 5 alternative config:</strong></p>
  <pre><code>private static void RegisterWcfClient&lt;TIService, TClient&gt;(this IServiceCollection services, string baseUrl,
      string serviceName, string certName, string storeLocation)
      where TIService : class
      where TClient : ClientBase&lt;TIService&gt;, new()
  {
      services.AddScoped(servicesCollection =&gt;
      {
          var client = new TClient();
          var customBinding = new WSHttpBinding(SecurityMode.Transport, false);
  
  
          customBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
          customBinding.ReaderQuotas.MaxDepth = 2147483647;
          customBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
          customBinding.ReaderQuotas.MaxArrayLength = 2147483647;
          customBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
          customBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
  
          customBinding.CloseTimeout = new TimeSpan(0, 10, 0);
          customBinding.OpenTimeout = new TimeSpan(0, 10, 0);
          customBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
          customBinding.SendTimeout = new TimeSpan(0, 10, 0);
          customBinding.BypassProxyOnLocal = false;
          customBinding.TransactionFlow = false;
          customBinding.MaxBufferPoolSize = 2147483647;
          customBinding.MaxReceivedMessageSize = 2147483647;
          customBinding.TextEncoding = Encoding.UTF8;
          customBinding.UseDefaultWebProxy = true;
          customBinding.AllowCookies = false;
  
  
          customBinding.ReliableSession.Ordered = true;
          customBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 10, 0);
  
          client.Endpoint.Binding = customBinding;
          client.Endpoint.Address = new EndpointAddress($&quot;{baseUrl}/{serviceName}&quot;);
  
  
          var storeLocationEnum = ToStoreLocationEnum(storeLocation);
          client.ClientCredentials.ClientCertificate.SetCertificate(storeLocationEnum, StoreName.My,
              X509FindType.FindBySubjectName, certName);
  
          return client;
      });
  
      services.AddScoped(servicesCollection =&gt;
      {
          var factory = servicesCollection.GetService&lt;TClient&gt;()?.ChannelFactory;
          return factory.CreateChannel();
      });
  }
  </code></pre>
  <p>It works fine for small requests but for bigger requests I am getting mentioned exception.
  I created .NET 4.6.1 WCF client from the scratch basing on configuration I have in .NET 5 and it all works fine on .NET 4.6.1.
  Regarding exception - first time I am sending request it takes exactly 20 seconds for error to appear. For next requests its much faster (like 1-2 seconds).</p>
  <p><strong>My investigation so far:</strong></p>
  <ul>
  <li>Created issue on official WCF repo <a href="https://github.com/dotnet/wcf/issues/4751" rel="nofollow noreferrer">https://github.com/dotnet/wcf/issues/4751</a></li>
  <li>Disabled certificate revocation checks on server with no success</li>
  <li>Checked Event Viewer and PerfView for any related exceptions and didn't find any</li>
  <li>Tried modify Connection header on HTTP request with no success</li>
  </ul>
  <p>I dont have an idea whats the root cause of this error. It seems like a server-side problem but then why is it working fine for .NET 4.6.1 client?</p>
  <p>Any idea what could be wrong there?</p>