Repository navigation
HttpClient ObjectDisposed after SDK upgrade from 34.0.95 -> 34.0.113 #115611
Description
Android framework version
net8.0-android
Affected platform version
Android SDK 34.0.113
Description
Hello, and thank you for this amazing project.
We have a mobile application running MAUI in hospitals in Norway, where Android is one of the most used platforms. We needed to deliver a new version this week. Last Wednesday / Thursday we noticed that we started getting sporadic http client disposal messages. After some time we figured out that the only changes to the app was the Android SDK version delivered by .NET . 34.0.113 was released, and we noticed that pinning to 34.0.95 fixed the issues.
After a lot of times, I've actually not been able to give you a reproducible project , and due to internal policies in my company I am unable to share my project.
But I can give you a brief explanation of the architecture surrounding http client in the project:
- We reuse our HttpClients as much as we can in between different pages.
- We add our own DelegatingHandlers to make sure we add ticket, add logging etc.
- We use Polly for timeouts.
The times I often see it is when I navigate between two pages that is using the same http client, but is using it against different request urls.
Here is the exception we keep seeing:
ObjectDisposed_Generic
ObjectDisposed_ObjectName_Name, Java.IO.InputStreamInvoker
System.ObjectDisposedException: ObjectDisposed_Generic
ObjectDisposed_ObjectName_Name, Java.IO.InputStreamInvoker
at Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable )
at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String , IJavaPeerable , JniArgumentValue* )
at Java.IO.InputStream.Close()
at Android.Runtime.InputStreamInvoker.Close()
at System.IO.Stream.Dispose()
at System.IO.BufferedStream.Dispose(Boolean )
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at System.Net.Http.StreamContent.Dispose(Boolean )
at System.Net.Http.HttpContent.Dispose()
at System.Net.Http.HttpResponseMessage.Dispose(Boolean )
at Xamarin.Android.Net.AndroidHttpResponseMessage.Dispose(Boolean )
at System.Net.Http.HttpResponseMessage.Dispose()
at System.Net.Http.HttpClient.HandleFailure(Exception , Boolean , HttpResponseMessage , CancellationTokenSource , CancellationToken , CancellationTokenSource )
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage , HttpCompletionOption , CancellationTokenSource , Boolean , CancellationTokenSource , CancellationToken )I understand that this a long shot as I do not have a reproducible project, but I hope that anyone in the team / community can reach out and see if they might have broken something, or have an idea on what we are potentially doing wrong.
Appreciate your time!
Steps to Reproduce
None unfortunately.
Did you find any workaround?
For now, we pin the SDK version by using the rollback feature of dotnet workload install, which saved our delivery, but we plan to upgrade every bits and pieces soon, so this will soon be an issue for us again.
Relevant log output
No response
Activity
jpobst commentedon Jun 18, 2024
@simonrozsival Now that we are part of the
dotnetGitHub organization, should I transfer HTTP issues like this todotnet/runtime?simonrozsival commentedon Jun 18, 2024
@jpobst this might be an issue in
Xamarin.Android.Net.AndroidHttpResponseMessage.Dispose(Boolean )so I would keep it in theandroidrepo for now, until we can say that this issue doesn't belong here.haavamoa commentedon Jun 18, 2024
I forgot to mention another work around I've had success with:
This might end up with throwing another dispose exception, or not. I've added a 5 second retry, which will end up with a success at some point during those 5 seconds.
If you are interested:
Here's my HttpClient helper class that gets run when an
ObjectDisposedExceptionoccurs in a DelegateHandler:haavamoa commentedon Jun 18, 2024
@simonrozsival: Just shout out if you need me to test potential nightly builds or something in our project.
simonrozsival commentedon Jun 18, 2024
@haavamoa can you please share more information about the settings you're using with the client? I'm especially interested in automatic decompression, built-in authentication (Basic?, NTLM?), proxies, ... Also are you able to tell what happened with the request just before it threw the exception (redirect, 4xx error, 5xx error)? Does this happen for a specific HTTP method or does it happen both with and without any body sent to the server?
haavamoa commentedon Jun 19, 2024
Hi @simonrozsival.
We've seen this bug on both HttpClients that is using authentication, but also on HttpClients which his not. For the ones that do ; we are using built-in-authentication using Bearer Token from the Identity Model flow. We've not set any decompression or proxies to our HttpClients.
No requests have failed before we do the calls. One example is simply trying to reach a /status/ping endpoint which does nothing more than return 200 OK. This fail sporadicly. It happens for all kinds of HTTP methods, with or without bodies.
I've spent days trying to see the connection between the order of doing calls, or what happens to them before it fails, but I am unable to find a pattern at all. From my point of view it can happen to any call we do regardless of the situation, which I find too good to be true to be honest.
simonrozsival commentedon Jun 19, 2024
Thanks for the details, @haavamoa. I remember seeing reports of
ObjectDisposedExceptionbeing thrown before but we've never been able to reproduce it. I will try to repro this again to see if I can narrow down what could cause this exception.If you think of any additional details (are you making requests in parallel or just one at a time, you're making requests always when the app is in foreground or if the app is in background, ...) or if you're able to repro it reliably, please let me know.
simonrozsival commentedon Jun 19, 2024
@haavamoa could you try building your app with
<UseNativeHttpHandler>false</UseNativeHttpHandler>? That will internally changeAndroidMessageHandlerforSocketsHttpHandlerand it might help you avoid this issue altogether.zachdean commentedon Jun 20, 2024
Hey @simonrozsival, I have started observing this exception randomly in our http requests (MAUI) after the tooling was upgraded to Android SDK 34.0.113. Looking through our logs I do not see any discernable patterns for when the failure happens.
simonrozsival commentedon Jun 20, 2024
@zachdean do you have any stacktraces you can share? Are you able to reproduce the exception in your app?
kmiterror commentedon Jun 21, 2024
Same happens for us after workload was updated to 34.0.113
34.0.95 works ok
As a workaround we will try this:
Make a file like this named
workload.json:{
"microsoft.net.sdk.android": "34.0.95/8.0.100"
}
Then
dotnet workload update --from-rollback-file $(androidProjectFolder)/workload.jsonshould install 34.0.95.Stacktrace of the crash:
simonrozsival commentedon Jun 21, 2024
@zachdean do you also use Polly?
122 remaining items
dotnet-policy-service commentedon Aug 27, 2025
This issue has been automatically marked
no-recent-activitybecause it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will removeno-recent-activity.b12kab commentedon Aug 28, 2025
activity!
simonrozsival commentedon Aug 28, 2025
@b12kab have you been able to test the servicing release with the GC fix? can you still reproduce the issue even with that release?
b12kab commentedon Sep 3, 2025
Our PO decided to push it until next release.
I personally tried it, and didn't have any issues.
b12kab commentedon Sep 5, 2025
@simonrozsival I'm writing this up to pull in for next release; we hardcode our workload versions, to make builds repeatable.
Which android workload is this in 35.0.78 or 35.0.92? I looked them over and wasn't 100% sure.
dhindrik commentedon Sep 12, 2025
We got rid of all our ObjectDisposed exceptions related to HttpClient after the August release (9.08).
Note, we also started to use SDK 36 at that time, but I guess that is not what fixed it.
simonrozsival commentedon Sep 12, 2025
@b12kab I am not 100% sure if 35.0.78 contains the fix, but .92 and .101 definitely do.
simonrozsival commentedon Sep 12, 2025
@dhindrik thanks for the report.
I am closing this issue now. Please feel free to reopen the issue if you can still reproduce the bug in .NET 9 Servicing, Android 35.0.101 and later or .NET 10 RC 1, Android 36.0.0-rc.1.285 or later.
IeuanWalker commentedon Sep 15, 2025
@simonrozsival @jonathanpeppers how do we make sure we are using the fixed version in maui?
we are running into this issue, our pipeline installs maui by doing -
dotnet workload install maui --version 9.0.102.1we also have the same in our global.json -
{ "sdk": { "version": "9.0.102" } }dhindrik commentedon Sep 15, 2025
I guess you need to specify the updated .NET version. We are using 9.0.x in our pipeline, but not for MAUI workload, just for .NET. Leaving it for out for MAUI, it will install it based on your .NET version.
If you want to specify, you should use 9.0.304.
jonathanpeppers commentedon Sep 15, 2025
The fix for this issue is in the runtime.
The best way to figure out your version of the runtime, is
dotnet --info, an example on Windows:Assuming you're not pinning your workload (with a rollback file or workload set), using the latest .NET SDK should update it.
akoeplinger commentedon Sep 15, 2025
The latest SDK in the 9.0.1xx band is 9.0.110