reverse-proxy: Random 502 errors when client cancels request
Random 502 errors when ui cancels the request.
We have an Angular UI application that talks to an ASP.NET webservice hosted in IIS and proxyed with YARP. The backend only works with HTTP1.1 not HTTP/2 The error happens only if YARP uses HTTP/2, so the error happens only when YARP needs to proxy HTTP/2 traffic to a HTTP1.1 backend. The application works as usual and we have some custom ui logic that cancels some of the requests, when the requests is cancelled YARP returns 502.
To Reproduce
I had not created a reproducible working scenario but I think that it is enough to issue a request then immediately cancels. From the browser I can see that the request has content-lenght of some bytes (49 in the above example) but the request was cancelled before the first byte of the content was transmitted so YARP complained.
2023-03-14 14:52:36.832 +01:00 [INF] Proxying to http://localhost/api/v1/omnisearch/view-config HTTP/2 RequestVersionOrLower no-streaming
2023-03-14 14:52:36.836 +01:00 [INF] "Request": An error was encountered before receiving a response.
System.Net.Http.HttpRequestException: Sent 0 request content bytes, but Content-Length promised 49.
at System.Net.Http.HttpConnection.SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, 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.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at Yarp.ReverseProxy.Forwarder.HttpForwarder.SendAsync(HttpContext context, String destinationPrefix, HttpMessageInvoker httpClient, ForwarderRequestConfig requestConfig, HttpTransformer transformer, CancellationToken cancellationToken)
Further technical details
- Latest YARP packages, on .NET 7 windows environment.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 1
- Comments: 17 (7 by maintainers)
Sorry I merged it a bit fast, it should be ok now
Sorry for not coming back sooner.
If I do launch the demo with
dotnet run --project ...I see the exception. If I run the dlls directly withdotnet xxx.dllthe repro doesn’t work (not sure why I tried first that way).We should be able to do a workaround for this issue soon.
Thanks again for the repro.
Hello @MihaZupan Hello @alkampfergit
We have encountered the same problem in our environment. The problem has been found with update to Yarp 2.0.
But here with a Blazor Wasm client, SingalR and GRPC. The problem seems to occur only with Kestrel. In an IIS environment the problem seems to occur less often.
Attached you can find a sample application consisting of a WASM client which opens a SignalR connection and then makes a GRPC call. Then the SignalR connection is closed and another GRPC call is made. This is done in a loop until the error occurs. The problem can be reproduced more quickly in Chrome than in Firefox. ProblemDemo.zip
With Yarp, the error occurs after about 120 runs:
Without Yarp the whole thing runs stable:
What’s interesting is that the client can’t make any other calls to the server at all after the error. The error occurs then immediately. If you wait about 30 seconds, the system recovers and several calls are possible again.
How is it canceled, but not considered canceled? Can you share a runnable repro js script we could use that demonstrates that?
You’re in luck, this was just recently changed to warning in main: #2044