-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HttpClient.GetStringAsync Suppressed Exceptions Cause Deadlock #34164
Comments
When you say "deadlock" you mean the request simply never returns? What happens when you decrease |
https://www.ssllabs.com/ssltest/analyze.html?d=beautymatter.com reports some unusual errors in the TLS server certificate chain. Not sure if this might be related to the reported "hang" problem with HttpClient, including an additional certificate being returned from the server that doesn't appear to be in the proper chain of trust for the server certificate: |
I believe that "Certificate #2" is "the certificate we get if we don't include the SNI header", which matches what I see in |
Decreasing timeout has no discernable effect. |
The GetAsync call throws the following exceptions. I'm not experienced enough to read into it. The issue is not so much about the exception or hang, it is the missing exception by the GetStringAsync that is the issue. Deadlock is the worst outcome.
and this...
|
I reported this issue before at #31259 👍 Here is the relevant code:
In dotnet core 3.1 these methods do not have the cancellation token overloads yet, but still specify The fact is that any usage of Here is a live repro of the issue that shows the dangerous behavior https://dotnetfiddle.net/UpFwOD - I had to set the timeout to 3 seconds due to dotnet fiddle runtime limitations but if you copy the code you will see that it permanently deadlocks indefinitely. Full framework had a 300 second default timeout for idle sockets, but for some reason that was never added to dotnet core. I strongly maintain that in order to make httpclient safe for customers to use, either a way to set a global idle socket timeout must be provided or all calls that use Let me give an example of how many of your customers this current behavior is endangering: Did you know that the AWS SDK, with 52,965,649 downloads total and close to 30k downloads per day forces HttpCompletionOption.ResponseHeadersRead on all outbound .net core requests? And how ( until 8 days ago - omg they added their first async overload ) their MD5 Wrapper stream that wraps all their responses does not provide async method overloads And how the base And how this all results in customers thinking their usage of a Stream is safe against deadlocks because they passed in a cancellation token, which silently and unbeknownst to them actually doesn't do anything because some stream implementation in the chain didn't overload one of the async methods? AWS Services are fairly reliable, but I've experienced multiple time - on production services mind you - that S3 got into a bad state where it never closes the connection, deadlocking our production service. Worse yet, it seems to take a few minutes for AWS to realize something is wrong and take the faulty S3 service out of rotation. Since calls to S3 are behind a round robin load balancer it means that literally every service in the entire AZ gets deadlocked. Oh yeah, restarting the services right away doesn't work either since the faulty S3 service is still in rotation. The point I am trying to make is that if AWS makes a single mistake with the configuration of their servers, all dotnet core apps using AWS will deadlock. Period. And will remain deadlocked until they are restarted - even if AWS fixes the issue on their end right away. Just ... let us configure a timeout for idle sockets & give us a IAsyncStream interface so we can start building modern, fully-async streams 😢 Or at the very least, for non-overloaded async methods with cancellation token register a callback that closes the stream if the cancellation token is cancelled prior to completion, like so: Edit: also this has been reported over a year ago at #28404 (comment) but the root issues have yet to be addressed. |
Triage:
|
it's surprising to me that this is 'up-for-grabs' and not higher priority. this bug (and the other related missing timeout/token API issues) renders |
Just confirm, seems current issue has been fixed in PR. Is it correct? Or still has something we can participate on this, thanks :) |
HttpClient.GetStringAsync Suppressed Exceptions Cause Deadlock
.NET Core 3.1 running on Windows 10. Console application using default template, entire application code is included below.
I found a website, beautymatter.com, that causes an unusual deadlock when using HttpClient. The site has some odd configurations that result in random I/O connection failures (~10% of the time) that incidentally make it an excellent platform to test for edge-cases.
What I discovered is that the HttpClient.GetStringAsync appears to be suppressing exceptions and entering permanent deadlock when the transport stream fails to close properly. HttpClient.GetAsync correctly throws exceptions for these transport errors.
The text was updated successfully, but these errors were encountered: