Skip to content
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

ProtocolException: unexpected end of stream while downloading a file #3715

Closed
ali-idrizi opened this issue Dec 9, 2017 · 48 comments
Closed
Labels
needs info More information needed from reporter
Milestone

Comments

@ali-idrizi
Copy link

ali-idrizi commented Dec 9, 2017

Using a library which uses okhttp to download files, I am usually getting an unexpected end of stream error while downloading large files (thrown at the end of the download). I am using the following code and URL to reproduce the error:

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://speedtest-sfo1.digitalocean.com/100mb.test").build();
client.newCall(request).enqueue(new Callback() {
	public void onFailure(Call call, IOException e) {
		e.printStackTrace();
	}

	public void onResponse(Call call, Response response) throws IOException {
		if (!response.isSuccessful()) {
			throw new IOException("Failed to download file: " + response);
		}

		FileOutputStream fos = new FileOutputStream(downloadDirectory + File.separator + "100mb.test");
		fos.write(response.body().bytes());
		fos.close();
	}
});

URL: http://speedtest-sfo1.digitalocean.com/100mb.test (This is not the only URL the error is thrown on)

The code has been tested on API 22, 25, 26, 27. The error is not thrown always, I tested it 10 times and got the error 6 times, 4 times the file got successfully downloaded and saved..

I have read about the error and I know that it gets thrown when the servers sends incorrect Content-Length, not this time though. The file is exactly 100MB and the server supplies its correct length. I am not sending any extra request headers, the response headers are:

Server => nginx/1.13.3
Date => Sat, 09 Dec 2017 17:19:31 GMT
Content-Type => text/plain
Content-Length => 104857600
Last-Modified => Mon, 27 Nov 2017 09:11:00 GMT
Connection => close
ETag => "5a1bd6a4-6400000"
Access-Control-Allow-Origin => *
Access-Control-Allow-Headers => Origin,X-RequestedWith,Content-Type,Range
Access-Control-Allow-Methods => GET, OPTIONS
Accept-Ranges => bytes
Cache-Control => max-age=0, no-cache, no-store, mustrevalidate, no-transform

The complete error:

Callback failure for call to http://speedtest-sfo1.digitalocean.com/...
java.net.ProtocolException: unexpected end of stream
    at okhttp3.internal.http1.Http1Codec$FixedLengthSource.read(Http1Codec.java:406)
    at okio.Buffer.writeAll(Buffer.java:1005)
    at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:107)
    at okhttp3.ResponseBody.bytes(ResponseBody.java:136)
    at dm.com.downloadmanager.MainActivity$3.onResponse(MainActivity.java:273)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
@yschimke
Copy link
Collaborator

I haven't been able to reproduce. If you can make a reproducible test it would help a lot.

But have you considered avoiding reading into memory and streaming to the file instead? response.body().bytes() doesn't seem ideal.

@yschimke yschimke added the needs info More information needed from reporter label Dec 10, 2017
@ali-idrizi
Copy link
Author

ali-idrizi commented Dec 10, 2017

Yes I am aware of that, it was just for the test (tried to make it as simple as possible), otherwise I am using a multi-thread library that does just that. The exception may not be thrown in every download, so you will have to try a few times. It is happening much more often using the library because if a thread fails the whole download does too.

I made a simple app to demonstrate the error. I changed the download URL to another one that has 10MB (same case, correct content-length), so it is faster and has to use less memory. The download stops at the last byte I think (according to the attached screenshot). I tried the app only on Android emulator API 26.

App: https://github.com/ali-idrizi/OkHttp-ProtocolException

img

@swankjesse
Copy link
Member

Your test code definitely shouldn't be failing like this. Something is broken in OkHttp or the Android runtime.

@yschimke
Copy link
Collaborator

Thanks for making the sample app. I still can't get it to fail after about 30 requests

12-10 19:32:03.223 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:32:03.230 3972-3972/testaapp.okhttp.com.okhttpprotocolexception D/NetworkSecurityConfig: No Network Security Config specified, using platform default
12-10 19:32:07.785 3972-3994/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:32:08.926 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:32:13.500 3972-3999/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:32:14.448 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:32:28.192 3972-4005/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:32:29.690 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:32:34.972 3972-4011/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:32:36.237 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:32:40.833 3972-4017/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:34:03.427 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:34:03.630 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:34:04.001 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:34:04.394 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:34:04.602 3972-3972/testaapp.okhttp.com.okhttpprotocolexception I/Main: start
12-10 19:34:12.827 3972-4062/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:34:13.526 3972-4060/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:34:13.617 3972-4066/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:34:14.030 3972-4069/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760
12-10 19:34:14.391 3972-4068/testaapp.okhttp.com.okhttpprotocolexception I/Main: bytes 10485760

@ali-idrizi
Copy link
Author

I have no idea why this is happening. I just run it again and got the exception on the first request. I tried different OkHttp versions and compile options, the same thing happens over and over again.

12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp: Callback failure for call to http://speedtest-sfo1.digitalocean.com/...
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp: java.net.ProtocolException: unexpected end of stream
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at okhttp3.internal.http1.Http1Codec$FixedLengthSource.read(Http1Codec.java:406)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at okio.Buffer.writeAll(Buffer.java:1005)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at okio.RealBufferedSource.readByteArray(RealBufferedSource.java:107)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at okhttp3.ResponseBody.bytes(ResponseBody.java:136)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at testapp.okhttp.com.okhttpprotocolexception.MainActivity$1.onResponse(MainActivity.java:56)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
12-10 21:00:13.638 482-649/testaapp.okhttp.com.okhttpprotocolexception D/OkHttp:     at java.lang.Thread.run(Thread.java:764)

Its worth noting that there is also different people having these issues like #3682, and some also at the library I'm using https://github.com/lingochamp/FileDownloader/issues

@swankjesse
Copy link
Member

@ali-idrizi does this occur on all devices?

@ali-idrizi
Copy link
Author

I just tried it on a macOS and it does not happen, I also tried it on a real device running Android 5.1 and it doesn't either. So I am not sure what is the problem here, maybe the emulators?

@Aaron8899
Copy link

I had similar issue when file upload, but I just change logging level with basic from body then it works fine.

@swankjesse
Copy link
Member

Which devices does this occur on? X86 or ARM emulator? Running on which OS? We may end up finding a bug in a layer under OkHttp.

@Aaron8899
Copy link

In my case, It occurs on Android OS in Galaxy S7 and I don't test other devices.
I'm using OkHttp through Fast Android Network.

@ali-idrizi
Copy link
Author

For me it is happening on all devices I have tested it on this laptop, all of them are x86. I am running Windows 10 Pro. I will test the app on an ARM emulator and update.

@ali-idrizi
Copy link
Author

It does happen on ARM too, I tried it on different network/router, same story. So I guess there is something wrong with my system.

@yschimke
Copy link
Collaborator

@ali-idrizi I was really interested that you could reproduce so easily with your sample app that doesn't do anything fancy. The threading of the FileDownloader library means there are more places the bug could be, but your sample app was a normal download.

@ali-idrizi
Copy link
Author

ali-idrizi commented Dec 11, 2017

@yschimke I know, but exactly the same app is throwing an exception when I try it. I am not doing anything else except debugging the app on an API 26 x86 emulator and the exception is thrown just like in the screenshot above.

I firstly thought it was specific to some URLs, but later on I realized it happens on every URL and emulator from my system.

@yschimke
Copy link
Collaborator

Does it happen without breakpoints?

@ali-idrizi
Copy link
Author

Yes it does.

@Javisilox
Copy link

Javisilox commented Jan 5, 2018

Hi, I'm getting the same exception uploading a video of 100 kb, the content lenght seems right, I'm working with a Samsung Galaxy S6 with Android 6.0.1.

Did you find any soution?

Edit to say that in my case it was a stupid mistake and not a bug, my video file was corrupted...

@Shelmanxie
Copy link

Shelmanxie commented Jan 23, 2018

HI ,I got the same problem on STB ,Android version is 4.4.2. the content length is right, While downloading a file with length of 319318529 ,it stops with this error at 40% downloading.
Did you find the solution to this problem?

@ali-idrizi
Copy link
Author

No, in my case it was a problem with my laptop, and it still happens, but it works pretty good on other devices I have tried.

@Shelmanxie
Copy link

@swankjesse @ali-idrizi : In my case , it works fine with server on Apache Server 2.2 . But when it comes to Apache Server 2.4, the problem occurs. Hope this could help you find the solution to the problem.

@swankjesse swankjesse added this to the 3.11 milestone Feb 18, 2018
@swankjesse
Copy link
Member

Unsure what action to take on this. An executable test case would be really handy.

@Shelmanxie
Copy link

Shelmanxie commented Feb 24, 2018

Hi , I write a demo on Android platform,just a simple download action . You can click the button to trigger it.But the button click action dose nothing currently . You may pass your own remote file URL and other parameters. Hope this would help you ,3ks in advance.
https://github.com/Shelmanxie/OkhttpBugUnExceptedDemo

@yschimke
Copy link
Collaborator

@Shelmanxie If it's useful I've got a test app https://github.com/yschimke/okhttp-testapp you can build on also.

image

@yschimke
Copy link
Collaborator

yschimke commented Feb 24, 2018

@Shelmanxie I changed the app to have sensible default url and download paths, but it doesn't reproduce the problem on Android 16 or 25 emulators. I'm closing this for now, please reopen with a reproduction for us.

BTW I do appreciate the test app, thanks for doing that.

@Shelmanxie
Copy link

@yschimke Hi, you may use a file that its size is beyond 300M and the server should be Apache Server 2.4. Try it, and you may reproduce it. Android version may not be the cause of this problem.

@yschimke
Copy link
Collaborator

OK, trying your app with https://speed.hetzner.de/1GB.bin

If it passes for me, we will be back to needing some logs, including things like proxies that are in use. Maybe it's something like data caps. n.b. Does it fail for you on https addresses as well, I've been mostly testing with secure traffic.

@Shelmanxie
Copy link

As for https address, we didn't use it in our business scene. As I mentioned above, file size which is beyond 300M and Apache Server 2.4 cause this problem.

@yschimke
Copy link
Collaborator

OK, I don't have an Apache Server 2.4 with a 300M file available to me. Please reopen if you can provide one and I'll test with it.

@Shelmanxie
Copy link

Sorry ,I am afraid that I can't provide one for you, cause I don't own a public IP address or a remote server. So I test it with my own computer providing a local Apache 2.4 server .I do have a Apache server 2.4 software package available,but the upload speed to github in my country is too too slow because of the network wall,there's no possibility to have a success upload of the package. Maybe you need to make a local server by yourself . Sorry again...

@japer21
Copy link

japer21 commented Jun 1, 2018

I have the same issue over and over again.
I am using Android emultor, Pixel API27, Android 8.1, CPU x86 and the version of okhttp is 3.10.0

@aimran50
Copy link

I too am having the exact same issue. I am using HttpURLConnection as documented here: https://developer.android.com/reference/java/net/HttpURLConnection.

The app makes lots of connections and transfers small amount of data(in kb range).

After about 4 to 5 requests, the "unexpected end of stream error" is seen. Everything halts for some time and then resumes.

Happens on hardware as well as emulator.
Emulator: Android 8.1 , API 27
Phone: Android 8.0
Do not see this error on API 23. So, it appears something added after that version is causing this.

Here's the stacktrace:
Caused by: java.net.ProtocolException: unexpected end of stream
06-27 14:19:04.306 3854-3956/com.myapp.android W/System.err: at com.android.okhttp.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:396)
at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:371)
at java.io.InputStream.read(InputStream.java:101)

Perhaps this should be reopened and looked at again?

@swankjesse
Copy link
Member

@aimran50 can you provide an executable test case?

@aimran50
Copy link

aimran50 commented Jul 2, 2018 via email

@andrewleech
Copy link

I'm very regularly getting the same error in an app using the HERE SDK (mapping library) https://www.developer.here.com/documentation/android-premium/dev_guide/topics/maps.html

In case it helps, here is the stack trace:

E/NetworkProtocol(  375): NetworkProtocol::GetTask::run exception: java.net.ProtocolException: unexpected end of stream
W/System.err(  375): java.net.ProtocolException: unexpected end of stream
W/System.err(  375): 	at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:449)
W/System.err(  375): 	at com.android.okio.RealBufferedSource$1.read(RealBufferedSource.java:168)
W/System.err(  375): 	at java.io.BufferedInputStream.read(BufferedInputStream.java:290)
W/System.err(  375): 	at java.io.InputStream.read(InputStream.java:162)
W/System.err(  375): 	at com.here.network.NetworkProtocol$GetTask.doInBackground(NetworkProtocol.java:418)
W/System.err(  375): 	at com.here.network.NetworkProtocol$GetTask.doInBackground(NetworkProtocol.java:181)
W/System.err(  375): 	at android.os.AsyncTask$2.call(AsyncTask.java:327)
W/System.err(  375): 	at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err(  375): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err(  375): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err(  375): 	at java.lang.Thread.run(Thread.java:818)

This is on an android device whose only internet connection is via a bluetooth tether to android phone, so is rather slow.
I haven't seen the issue in an app using the same version of the HERE SDK running on the android phone (with fast wifi connection)

@swankjesse
Copy link
Member

@andrewleech sounds like a bug in the connection between client and server. The client isn't reading fast enough so the server truncates the response.

@LightSun
Copy link

@swankjesse i agree . i have the problem too. the file size is 51KB.

@emileb
Copy link

emileb commented Dec 4, 2018

Has anyone found solution to this? I can cause it if I artifically slow down the download. On API 28 downloading a 30MB file from my server. Need to get the fixed ASAP as causing issues for user. Any help appreciated!

@Shelmanxie
Copy link

hello ,I fix this by changing Apache configuration. just like the picture shows below.
image

@Shelmanxie
Copy link

so ,it seems like a server problem.

@thesiamak
Copy link

I had the exact same problem with uploading small files to server and it seems solved by changing logging level! Strange!
AndroidNetworking.enableLogging(HttpLoggingInterceptor.Level.BODY);
To
AndroidNetworking.enableLogging(HttpLoggingInterceptor.Level.BASIC);

@VijayBest
Copy link

I facing the same problem and use MAC OS and test it on Android 10

@rainyandsunny
Copy link

I facing the same problem on Honor 8X with Android 8.1.0

@LiarrDev
Copy link

Same issue.

I'm using:
OkHttp 4.8.0
Honor 10 Lite with Android 10

@DileepKumarkillari471
Copy link

any one know the solution, please tell ME

@rakesh-krishna
Copy link

I am also facing the same problem not sure how to handle it.
I am running a Flask Api

@skyzhw
Copy link

skyzhw commented Sep 17, 2021

In a specific series of models + a specific server + a specific Wifi network, the probability of this problem is very high, and it is also related to the network usage at the time. The problem I encountered is that the probability of occurrence is very high in Huawei mobile phones, Alibaba Cloud CDN and my company's Wifi. After verification, it is found that the default value of the ReceiveBufferSize of the socket in the Huawei system is 2097152, and the default value of the Samsung system is 1048576. The guess is related to the system tuning of this parameter. Adjust this parameter to below 49152, the probability of this problem is very low, and it is almost difficult to reproduce. You can also try if you encounter similar problems. Core code: new OkHttpClient.Builder().socketFactory(), socket.setReceiveBufferSize(49152);

@OnClickListener2048
Copy link

parameter

no use

@colorthoro
Copy link

It seems that capacitor uses okhttp too, the ProtocolException would be thrown( almost every time) strangly only on RUN mode, everything works perfectly on DEBUG mode( in Android Studio; the emulator is Android 11, x86).
V/Capacitor/Plugin: To native (Cordova plugin): callbackId: CordovaHttpPlugin1978864772, service: CordovaHttpPlugin, action: get, actionArgs: ["http:\/\/10.0.2.2:5000\/scanMusic",{"Connection":"close"},60,60,true,"json",3] W/Cordova-Plugin-HTTP: Generic request error com.silkimen.http.HttpRequest$HttpRequestException: java.net.ProtocolException: unexpected end of stream at com.silkimen.http.HttpRequest$Operation.call(HttpRequest.java:641) at com.silkimen.http.HttpRequest.copy(HttpRequest.java:2499) at com.silkimen.http.HttpRequest.receive(HttpRequest.java:1856) at com.silkimen.cordovahttp.CordovaHttpBase.processResponse(CordovaHttpBase.java:205) at com.silkimen.cordovahttp.CordovaHttpBase.run(CordovaHttpBase.java:84) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) Caused by: java.net.ProtocolException: unexpected end of stream at com.android.okhttp.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:398) at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:372) at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) at java.io.BufferedInputStream.read(BufferedInputStream.java:347) at java.io.FilterInputStream.read(FilterInputStream.java:107) at com.silkimen.http.HttpRequest$6.run(HttpRequest.java:2492) at com.silkimen.http.HttpRequest$6.run(HttpRequest.java:2486) at com.silkimen.http.HttpRequest$Operation.call(HttpRequest.java:635) at com.silkimen.http.HttpRequest.copy(HttpRequest.java:2499)  at com.silkimen.http.HttpRequest.receive(HttpRequest.java:1856)  at com.silkimen.cordovahttp.CordovaHttpBase.processResponse(CordovaHttpBase.java:205)  at com.silkimen.cordovahttp.CordovaHttpBase.run(CordovaHttpBase.java:84)  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)  at java.util.concurrent.FutureTask.run(FutureTask.java:266)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  at java.lang.Thread.run(Thread.java:923)  E/Capacitor/Console: File: http://localhost/js/app.82b8407c.js - Line 1 - Msg: There was an error with the request: unexpected end of stream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs info More information needed from reporter
Projects
None yet
Development

No branches or pull requests