We're getting an EOF exception with size=0 in the stream.
java.io.EOFException: \n not found: size=0 content=...
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:187)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:791)
at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:90)
(Forked from issue 1114.)
@swankjesse mentioned the following
My hypothesis is that these are just badly-behaving webservers, or proxy servers or something. In OkHttp 2.3 we're now including more information about the connection when this problem occurs. This happens to normal devices, like your Moto X 2014.
So this is the problem that I am running into and it doesn't seem to be the other issue [https://github.com/square/okhttp/issues/1518] related to corruption of data. @swankjesse , if you think it is the webserver, do you know what on the server might trigger this only a 5-10% of the time or maybe even less? Most of the time it works, but once in a while I get this response.
@simtse what device are you using?
We are using Nexus 4, Nexus 5, Samsung Galaxy S4, Galaxy Note 3, OnePlus One, Nexus 9, HTC One M7, HTC One S, HTC One One X, Moto X 2013. Those are the ones we use most often.
Getting this issue on Huawei P6-U06 4.2.2. The problem seems to appear quite often only while downloading large files e.g. 600 Mb. The only solution is to make a connection retry?(
I'am using a GET request.
Hi,
I am facing this issue during low traffic time, I have 24 threads connected to the influxdb server making batch/sec updates. Little insight might help.
Caused by: retrofit.RetrofitError: unexpected end of stream on Connection{
at retrofit.RetrofitError.networkError(RetrofitError.java:27)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at org.influxdb.impl.$Proxy5.write(Unknown Source) ~[na:na]
at org.influxdb.impl.InfluxDBImpl.write(InfluxDBImpl.java:126)
at
... 21 common frames omitted
Caused by: java.io.IOException: unexpected end of stream on Connection{
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:211)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:95)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:902)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:760)
at com.squareup.okhttp.Call.getResponse(Call.java:274)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201
at com.squareup.okhttp.Call.execute(Call.java:81)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
... 25 common frames omitted
Caused by: java.io.EOFException: \n not found: size=0 content=...
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
... 36 common frames omitted
Hi guys,
Are you aware of any workaround possible? The issue doesn't seem to happen on Android 5.0.2, but happens quite often on 4.1.2 and 4.1.4 (at least).
Thanks,
Ivam
Same issue here,
IOException is thrown in 3 ms every 10, 20 or 30 requests ...
OkHttpClient client = new OkHttpClient();
client.setRetryOnConnectionFailure(false);
HttpURLConnection connection = new OkUrlFactory(client).open(url);
It never happens with okhttp include in Lollipop.
Running into this issue? Please send me a test case!
I recreated this issue on OkHttp 2.4.0 in debug. I set a break point on the line "Response response = getResponse().getResponse();" in the HttpURLConnectionImpl# getHeaders() method. My tomcat server is configured connectionTimeout="10000" for SSL connector. So, if I hold the getHeaders() method and let the server to close the connection. The client side always complains:
"org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://xxx.xxx.xxx.xxx/myapplication/api/myservice": unexpected end of stream on Connection{xxx.xxx.xxx.xxx:443, proxy=DIRECT@ hostAddress=xxx.xxx.xxx.xxx cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA protocol=http/1.1} (recycle count=3); nested exception is java.io.IOException: unexpected end of stream on Connection{xxx.xxx.xxx.xxx:443, proxy=DIRECT@ hostAddress=xxx.xxx.xxx.xxx cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA protocol=http/1.1} (recycle count=3)
...
Caused by: java.io.IOException: unexpected end of stream on Connection{xxx.xxx.xxx.xxx:443, proxy=DIRECT@ hostAddress=xxx.xxx.xxx.xxx cipherSuite=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA protocol=http/1.1} (recycle count=3)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:211)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:793)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getHeaders(HttpURLConnectionImpl.java:150)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getHeaderFieldKey(HttpURLConnectionImpl.java:202)
at com.squareup.okhttp.internal.huc.DelegatingHttpsURLConnection.getHeaderFieldKey(DelegatingHttpsURLConnection.java:202)
at com.squareup.okhttp.internal.huc.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:25)
at org.springframework.http.client.SimpleClientHttpResponse.getHeaders(SimpleClientHttpResponse.java:92)
... 9 common frames omitted
Caused by: java.io.EOFException: \n not found: size=0 content=...
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:200)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
... 27 common frames omitted
I cannot image any reason that would cause the client spend more than 10s to read the response. Any idea?
@dmoneyUK could you isolate this into a test case? There's lots of examples in CallTest, and MockWebServer is pretty capable around setting up timeouts etc.
I'm getting the same problem while creating a Websocket: http://stackoverflow.com/questions/32161398/okhttp-websocket-unexpected-end-of-steam-on-connection
EDIT: Figured it out. The server was closing the connection and not sending any data back, due to a misconfiguration on my part. That said, maybe there could be a way to make that error clearer for the developer?
@anubiann00b In my case, the "Unexpected end of stream" was also caused by server's connection timeout. But the question why does the client spend so much time to read a simple response? My server side timeout is 10 second, and the request was not a file upload/download, it is supposed to complete in 1 second at most. I cannot find any log in server side showing the request is received.
@swankjesse Is there anyway to turn the okhttp log to debug level? In my case, the client spend too much time to read a simple response and server's connection timeout. i did not find any information about what happened there.
@dmoneyUK I recommend you try out https://charlesproxy.com to inspect your HTTP traffic. We may add trace logging to OkHttp, but we don't have it currently.
Hi, I found 90% of this kind of exceptions happening in my environment are from "GET" request. And I found a code block in httpengine as below:
private Connection createNextConnection() throws RouteException {
ConnectionPool pool = client.getConnectionPool();
// Always prefer pooled connections over new connections.
for (Connection pooled; (pooled = pool.get(address)) != null; ) {
if (networkRequest.method().equals("GET") || Internal.instance.isReadable(pooled)) {
return pooled;
}
closeQuietly(pooled.getSocket());
}
....
}
Can you tell me why the GET request does not need to check connection readable?
@dmoneyUK OkHttp can silently recover from those GET failures, and it’s more efficient to try and recover vs. test first. (The API to check whether a connection is readable is a bit of a hack!)
Still present in version 2.5.0 ...
with connection.setRequestProperty("Connection", "close"); there is no more errors, but it's not a valid solution ...
I solved this In my envrionment. In my case, when OkHttp tries to re-use a connection which has been closed by my tomcat server, the exception happens. My solution is to configure the tomcat server's "keepAliveTimeout" > than the client's connection timeout so that the server will never close a connection before the client.
Thanks @JakeWharton
If you called setRetryOnConnectionFailure(false); on your connection, you will never have a solution to prevent those i/o errors.
Java's sockets have per design no way of knowing TCP connections are in state CLOSE_WAIT without trying to read from them.
OkHTTP or whatever library you use will send data into the closed connection, try to read from it, (only then) realize that it was closed, open/use another one and send the request again.
Configuring a very long Keep-Alive duration on your servers will prevent most of the errors, but if your clients are behind any kind of proxies, your configuration won't be relevant anymore.
Also, if your servers handle many requests and connection, the ops team that configures your front servers might not like the ideas of having tens thousands of unused opened connections.
@swankjesse Do you think adding isReadable() check for GET request while retryOnConnectionFailure is set to false is good idea?
Im getting this on ~1/6 calls using POST
Caused by: java.io.EOFException: \n not found: size=0 content=...
If I do the post via curl all is fine...this on okhttp 2.6.0 on android 6.0
The same error here.
java.io.IOException: unexpected end of stream on Connection{192.168.10.22:443, proxy=DIRECT@ hostAddress=192.168.10.22 cipherSuite=TLS_RSA_WITH_AES_128_CBC_SHA protocol=http/1.1} (recycle count=0)
Caused by: java.io.EOFException: \n not found: size=0 content=...
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:201)
On okhttp 2.6.0 and android 6.0
I get this problem consistently on one particular REST service. PUT and DELETE requests fail with this error while GET on the same service works just fine and other services in the same network environment work with no problems.
The same PUT/DELETE also go through successfully when run through Charles Proxy in SSL proxying mode.
Tracing with Wireshark shows the following, comparing to the trace from the proxied request that works:
I don't know if it makes a difference but the URL is about 5500 bytes in size - a very long identifier embedded in it. In GET with this service endpoint the URLs are only around 660 bytes i.e. well below what fits in one packet.
Android versions 4.x-6.0, many devices including plain x86_64 6.0 emulator, OkHttp 2.5.0 and 2.6.0.
Ok, did an experiment and shortened the requestLine by replacing the 5+kB identifier with a shorter one "foo". The request went through all right and got the expected error message from backend. So maybe it's about the way long request lines are written out i.e. not waiting for ACKs before proceeding, and then a server-side component backs off rapidly. I'll contact the network infra people to see if there's some e.g. DoS prevention in load balancers/proxies here.
I frequently keep seeing this when using S3 Post Uploads from my Android app. This is the only reason that keeps us from removing the Apache Http client. We currently use okhttp for all api calls and image downloads but Apache Http client for uploads :/.
@ImGauravC is it possible for you to whip up a simple Android app or test case showing the problem?
I can post the code we use for S3 Post uploads.
S3Data object is populated using our server api and contains information about the S3 key, acl etc.
Here's the gist:
https://gist.github.com/ImGauravC/69dae436d9fe36377dd3
@ImGauravC the answer is here : https://github.com/square/okhttp/issues/1517#issuecomment-144069139
Well, the client always retries on connection failure i.e. the default is true, so you can ignore the part where I call setRetryOnConnectionFailure(true).
Also, I don't have control over the S3 servers. Moreover POST uploads work perfectly fine from the browser and when using the Apache client.
Thanks @ImGauravC, are you using connection pooling with Apache client?
We're using loopj's AsyncHttpClient for uploads (some legacy code surrouding the previous use of this lib for api calls) which under the hood uses the Android Apache client. So it should be using connection pooling because it doesn't do anything special with the client.
@ImGauravC can you reproduce this consistently? We can try to validate that this is occurring because amazon servers are closing the TCP connection.
I did some experiments with AsyncHttpClient and found they silently recover from a connection close. One example is here
https://github.com/apache/httpclient/blob/4.3.6/httpclient/src/main/java/org/apache/http/impl/conn/DefaultHttpResponseParser.java#L143
I'm wondering if this has been happening all along, but you've never noticed because the Apache client is silently retrying on your behalf.
Me too, I am getting "unexpected end of stream" caused by: java.io.EOFException: \n not found: size=0 content=...
I am using Volley with okHttp 3.2.0. Web server is based on Tomcat. it happens often, but not always (maybe 10% of POST requests). The iOS version of the same application does not have this problem, so it seems an issue that could be solved client side.
Are there any workarounds?
Caused by: java.io.IOException: unexpected end of stream on okhttp3.Address@96651c04
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:199)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:595)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:481)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:417)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:549)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:26)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:110)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: ... 1 more
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: Caused by: java.io.EOFException: \n not found: size=0 content=...
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:201)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:184)
02-26 11:44:10.952 29152-29152/at.spar.mobile.interspar_app W/System.err: ... 11 more
@riccardo-tesio please isolate this into a standalone test case. You might have some success with the logging interceptor to see what headers are triggering this behavior.
Here is a test that shows one scenario where this can happen:
@Test public void clientTakesTooLong() throws IOException {
server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AFTER_REQUEST));
RequestBody slowPoster = new RequestBody() {
@Override public MediaType contentType() {
return MediaType.parse("application/json");
}
@Override public void writeTo(BufferedSink sink) throws IOException {
try {
Thread.sleep(3000);
sink.writeUtf8("{}");
} catch (InterruptedException ignored) {
}
}
};
Request request = new Request.Builder()
.url(server.url("/"))
.post(slowPoster)
.build();
try {
client.newCall(request).execute();
fail();
} catch (IOException e) {
assertTrue(e.getCause() instanceof EOFException);
}
}
Seems like one workaround would be to retry the request in case of EOFException.
@swankjesse and @dave-r12 : thank you for your quick answers.
Interceptors are great tools, I didn't realized it before; using them I found the problem (it was a server-side defect) and built a workaround.
Thanks again.
@ZeWaren Thank you for your answer.
When I am using Retrofit v2.1.0
java.io.IOException: unexpected end of stream on okhttp3.Address@34845fb]
java.io.IOException: unexpected end of stream on okhttp3.Address@34845fb
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:199)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:775)
at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:86)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:760)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:613)
at okhttp3.RealCall.getResponse(RealCall.java:244)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.EOFException: \n not found: size=0 content=…
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:215)
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:184)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:775)
at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:86)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:760)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:613)
at okhttp3.RealCall.getResponse(RealCall.java:244)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
I am not getting proper solution how can i fixed it.
I came across this error but it was due to me using a request url specifying the wrong port on my test server (a Zookeeper port) i.e. it was my mistake.
Caused by: java.io.IOException: unexpected end of stream on okhttp3.Address@dc6c6002
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:199)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)
at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:708)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
at okhttp3.RealCall.getResponse(RealCall.java:241)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:203)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:187)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.EOFException: \n not found: size=0 content=...
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:201)
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:184)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)Â
at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)Â
at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)Â
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:708)Â
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)Â
at okhttp3.RealCall.getResponse(RealCall.java:241)Â
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)Â
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:203)Â
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:187)Â
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)Â
at okhttp3.RealCall.access$100(RealCall.java:30)Â
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)Â
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)Â
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)Â
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)Â
at java.lang.Thread.run(Thread.java:818)Â
I came across another unrelated issue that I wasn't sure if it was worth raising as an issue. Setting Content-Type as a header with an interceptor gets overwritten with "application/json" (possibly from JacksonConverterFactory) but when I set a Content-Type header in the interface using the @Header annotation it works fine. Should I raise this as a separate issue?
val interceptor: Interceptor = Interceptor { chain ->
val newRequest: Request = chain.request().newBuilder().addHeader("Content-Type", "application/vnd.kafka.v1+json").build()
chain.proceed(newRequest)
}
Chipping in to monitor the progress. I'm using this indirectly in an app that utilizes CloudRail for communication with Dropbox, GoogleDrive, OneDrive, and Box. I'm just guessing that none of the users are using Box because this exception happens with the other three services. Log attached.
2-1.txt
Edit: Running in Genymotion Android 6.0 image. Happens also in stock Android Emulator with 4.0.4.
Lots of exceptions from users with various Android versions and devices. Can provide further info if needed.
@MisterY are you using retryOnConnectionFailure(true) ?
@swankjesse Unfortunately, I'm not using the library directly and therefore have no direct influence on the parameters. Adding @PatrickStoklasa, who might try that approach.
What I did to circumvent this is use .retry(1) when issuing the network call in the client app code. This seems to work! It would probably indirectly support your suggestion.
In a test with 1-minute interval between network calls, the exception used to appear after 2-10 minutes. With .retry(1) the test has been going for over an hour without hiccups. This approach will work for now. I'm still happy to assist in resolving the original issue any way I can.
Guess I can retry the test with the app once Patrick adds your retry suggestion to the library, if not used already. Thanks for the hint!
I think it is because the keep-alive of get method.when the back response is http1.0, it is can not use the keep-alive. but the twice call will read the connection. so when the third call, it is work. the same as 5,7,9 is
work. 4,6,8 is fail
I'm using okhttp 3.5.0, still got this issue.
The option retryOnConnectionFailure is true by default on 3.5.0 (If I'm not mistaken).
Could someone tell me how to fix it?
@Eric-Lee-Handymam can you provide a small program to demonstrate? Typically this is either a bug in the webserver or a bad URL.
@swankjesse My situation is the same as WanYouZhi mentioned: For the same action, half of the requests throwed Exception, and the others are successful. However, all the requests were processed by the web server(Apache). But the other request(with different params) to the same server are all success(I use the same method to call).
Request http://local:8080/req3.0.php?_c=page&actid=100&g_tk=12313334, 100 times, 50 throwed exception, 50 success, 100 process.
Request http://local:8080/req3.0.php?_c=page&actid=101&g_tk=12313334&appid=123, all success.
However, this case was occurred in the production environment, I cannot reproduce this case in my local environment......
I wrote a test unit to send the request to the same server, and all the requests are successful, none of them throw Exception......
"Typically this is either a bug in the webserver or a bad URL"
My situation: half of the requests throwed Exception, and the others are successful. (Same request address, different params)
I suspect it’s a problem with the server. What happens if you add this header to your requests?
Connection: close
@swankjesse
Thanks for your tips.
I will try it tomorrow, cause the server is provided by others, I need his help to complete this test(add some game cards to my account).
Do u mean the web server give me a response with an empty result?
Yeah.
Hi, bro.
You're right.
His server give me an empty response in specific conditions.
Thanks for your help.
E/NotificationFragment: UserGetNotificationResp onFailure: unexpected end of stream on okhttp3.Address@dcd6238c
01-20 15:55:28.957 26859-26859/com.meetwo W/System.err: java.io.IOException: unexpected end of stream on okhttp3.Address@dcd6238c
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:199)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:775)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:86)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:760)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:613)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.RealCall.getResponse(RealCall.java:244)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:190)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.RealCall.access$100(RealCall.java:30)
01-20 15:55:28.963 26859-26859/com.meetwo W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
01-20 15:55:28.964 26859-26859/com.meetwo W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
01-20 15:55:28.964 26859-26859/com.meetwo W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
01-20 15:55:28.964 26859-26859/com.meetwo W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
01-20 15:55:28.964 26859-26859/com.meetwo W/System.err: at java.lang.Thread.run(Thread.java:761)
01-20 15:55:28.965 26859-26859/com.meetwo W/System.err: Caused by: java.io.EOFException: \n not found: size=0 content=…
01-20 15:55:28.966 26859-26859/com.meetwo W/System.err: at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:215)
01-20 15:55:28.966 26859-26859/com.meetwo W/System.err: at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:184)
01-20 15:55:28.966 26859-26859/com.meetwo W/System.err: ... 16 more
I can't figure out the exact reason why this happening,
I am checking using different devices, Version of my retrofit library is V2.1.0 and my request types are GET and POST mostly
And we are running on Apache tomcat servers.
In my case, exact issue using com.android.okhttp of Android 7.1.1 using POST request. Only for large requests (not too much)
Solution (after 1 day): switch off /switch on wifi router
After reading this, I'm kind of puzzled. I'm seeing this exception for a lot of our users. I'm using OkHttp 3.5.0. I don't change the default value of "retryOnConnectionFailure" to false – so retries should happen automatically.
What is the recommended workaround? Would implementing an interceptor that retries on zero size be an option?
@schildbach might be a server issue. Are the failed requests on recycled connections?
No further action on this.
I have same problem on upload a stream to S3, Caused by: java.io.EOFException: \n not found: limit=0 content=… already set retryOnConnectionFailure false
also set .addHeader("Connection", "close"), still occur
BWT, lastest okhttp version
@crossle did you fix the issue?
The issue can be easily reproduced by trying to download a source artifact from SourceForge, like https://master.dl.sourceforge.net/project/tyrex/tyrex/Tyrex%201.0.1/tyrex-1.0.1-src.tgz. Neither adding .addHeader("Connection", "close") to the request nor adding .retryOnConnectionFailure(true) to the client helps.
Given how big of a site SourceForge is, even if it was a server configuration issue, can we reopen this to track adding a work-around, @swankjesse? Also, I have no issues downloading that file with Firefox or curl.
EDIT: Turns out the problem with downloading from SourceForge can be avoided by upgrading to at least java 8u161.
Hi, anyone have solution for this problem?
How to resolve the issue?
java.io.IOException: unexpected end of stream on Connection{develop.by:8000, proxy=DIRECT@ hostAddress=develop.by/195.***.***.**:8000 cipherSuite=none protocol=http/1.1}
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:205)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:125)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.EOFException: \n not found: limit=0 content=…
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:227)
at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:212)
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
... 19 more
Code:
```
final Request request = new Request.Builder()
.get()
.url("http://develop.by:8000")
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
WebSocket webSocket = okHttpClient.newWebSocket(request, new WebSocketListener() {...}
```
Is the last solution good?
Why is this issue closed, if it looks like unsolved?.
I was working before with HttpUrlConnection and never experienced this problem. Server hasn't changed. So, probably the problem is with OkHttp.
Working with Android 4.4.
Server is Jetty based with Java 8.
I am having this problem too.
It started to occur since we switched our server to an S3 instance.
Hello, i'm facing this issue, reading this stackoverflow question says that this error is causing from the server. Any solution ?
I encountered this issue as well and was able to resolve it.
I was working with some existing code which used Retrofit. We have 3 different dev environments, the same endpoint was working fine in 2 of the environments, but I was getting this exception when using the third.
All 3 servers were returning the exact same 200 response.
The code I was working with was passing a boolean value of false as an empty @Body in a PUT call.
I changed this to an empty String instead and now it works fine, though I don't entirely understand why. Something somewhere must be looking for the null terminator character that an empty String provides.
For posterity: I ran into this error frequently when using the Square bindings for Xamarin, using an NetworkInterceptor. This crash is thrown frequently (as described before) but should be handled by the retry on connection code. But somehow in Xamarin it crashes in such a way the retry is never done, and the exception is propagated to the app.
I ran into this problem recently when I was sending requests to a web server that was still in the process of starting up (it was being started by a docker container), which seemed to cause the server to send empty headers back to the client. The solution in that case was to wait for the server to be completely up before sending requests.
i have same issue and i find some solution:
the problem is HttpLoggingInterceptor , when we use HttpLoggingInterceptor that time the error java.io.EOFException: \n not found: limit=1 content=0d… comes
and when i use bellow code that time error not cumming, but if we dont use HttpLoggingInterceptor then we can not see API call logs in android studio logcat :(
`public static Retrofit getRestAdapter() {
// HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
// interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("Connection", "close").build();
return chain.proceed(request);
}
});
return new Retrofit.Builder()
.baseUrl(Configuration.getBaseUrl())
.client(httpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
}`
i think if we can set Headers in HttpLoggingInterceptor then error can be solve but i didnt found any ways to set headers in HttpLoggingInterceptor object :(
anybody can help in this case please reply here ... thanks
Good news,
This issue resolved just by adding Connection header as @rasik1010 say but i'm still using HttpLoggingInterceptor and it's working fine.
addHeader("Connection", "close")
@rhonyabdullah where/how did you put addHeader("Connection", "close") in HttpLoggingInterceptor? can you share that code please?
@rasik1010 you are right, only disable the HttpLoggingInterceptor works for me. I tried addHeader("Connection", "close") and disable the Accept-Encoding gzip by updating the Accept-Encoding to "identity" , they both don't work @rhonyabdullah
Using okHttpVersion = "3.10.0"
I'm using kotlin, but it is still readable i think. I'm writing this answer without any IDE, i'm just using this comment box, sorry if any mistake:
internal fun OkHttpClient.Builder.defaultBuilder(isDebug: Boolean)
: OkHttpClient.Builder {
if (isDebug) {
addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
}
connectTimeout(ApiConstant.TIME_OUT_IN_SECONDS, TimeUnit.SECONDS)
readTimeout(ApiConstant.TIME_OUT_IN_SECONDS, TimeUnit.SECONDS)
writeTimeout(ApiConstant.TIME_OUT_IN_SECONDS, TimeUnit.SECONDS)
return this
}
private fun getRequestHeader(chain: Interceptor.Chain): Request {
return chain.request().newBuilder()
.addHeader("Connection", "close")
..(my another header params)
.build()
}
val clientBuilder: OkHttpClient.Builder = OkHttpClient.Builder().defaultBuilder(isDebug)
clientBuilder.addInterceptor { chain -> chain.proceed(getRequestHeader(chain)) }
return Retrofit.Builder()
.baseUrl(myBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(clientBuilder.build())
.build()
hi guys, recently we changed our server and now i am using bellow using HttpLoggingInterceptor and the error java.io.EOFException: \n not found: limit=1 content=0d… gone!!!!!
Now the issue is fixed, error was from server side, changed hosting server and issue was fixed automatically. earlier i was hosting on TSOHost where this issue was arraving
so i think this error its because of server
public static Retrofit getRestAdapter() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(interceptor);
return new Retrofit.Builder()
.baseUrl(Configuration.getBaseUrl())
.client(httpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
I faced the same issue Caused by: java.io.EOFException: \n not found: limit=0 content=….
The issue was when requests were made in conjunction with
Connection: keep-alive
Transfer-Encoding: chunked
with a long JSON response in the body, but the body was not written according to Chucked Transfer Encoding spec. https://en.wikipedia.org/wiki/Chunked_transfer_encoding
Like the suggestions above, adding Connection: close resolved the issue since it triggered to use UnknownLengthSource instead of ChunkedSource.
Alternative workaround is reading byte[] from ResponseBody.byteStream(), however this would mean the server response is not following Http1.1 spec where it sends Transfer-Encoding: chunked but the body format is not inserting
<< Size of chunk >>\r\n
<< Chunk body >>\r\n
...
repeat as many times
...
0\r\n
\r\n
OR,
the response header can specify Content-Length header.
I faced the same error / stacktrace but with another cause; therefore the described workarounds did not work for me.
My problem was the authentication at the server: In my application, I get URLs in the form http://user:[email protected]. The user information are extracted and sent to the server in the Authorization header. But the credentials have not been removed from the URL, so I the requests contained the credentials both in the headers and in the URL. This caused a server (Spring Boot application) to misbehave, causing the error described in this issue.
Removing the credentials from the URL solved the problem for me
.addHeader("Connection", "close")
Didn't worked.
For me this happened when i connected to a server with HTTP, but it actually should have used HTTPS, check your URL!
Most helpful comment
If you called
setRetryOnConnectionFailure(false);on your connection, you will never have a solution to prevent those i/o errors.Java's sockets have per design no way of knowing TCP connections are in state
CLOSE_WAITwithout trying to read from them.OkHTTP or whatever library you use will send data into the closed connection, try to read from it, (only then) realize that it was closed, open/use another one and send the request again.
Configuring a very long Keep-Alive duration on your servers will prevent most of the errors, but if your clients are behind any kind of proxies, your configuration won't be relevant anymore.
Also, if your servers handle many requests and connection, the ops team that configures your front servers might not like the ideas of having tens thousands of unused opened connections.