I'm using Retrofit 1.9.0 + OkHttp 2.3.0 + okhttp-urlconnection 2.3.0.
It works well on most android devices, but one Android 4.4.4 KTU840 phone (xiaomi - MI 4LTE).
The SocketTimeoutException often appear after one or more service calls.
Whenever the exception appeared, no more request can work well, I have to restart the application.
Is it a known bug?
When I remove okhttp-urlconnection and setup timeout of okhttp client, no help to solve it.
When I use UrlConnectionClient (provided by retrofit) instead of OkClient, it works well.
Sorry for my bad english!
Output of logcat:
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ ---> HTTP GET http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ Accept: application/json
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ User-Agent: XXX/1.1.0.3(beta) (App) Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 4LTE MIUI/V6.3.6.0.KXECNBL)
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ ---> END HTTP (no body)
07-27 16:49:52.615 30449-31180/com.xxx.xxx D/Retrofit﹕ ---- ERROR http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:52.638 30449-31180/com.xxx.xxx D/Retrofit﹕ java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:495)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
at okio.Okio$2.read(Okio.java:137)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:289)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at com.squareup.okhttp.internal.http.HttpConnection.readHeaders(HttpConnection.java:219)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:198)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:830)
at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:95)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:823)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:684)
at com.squareup.okhttp.Call.getResponse(Call.java:272)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
at com.squareup.okhttp.Call.execute(Call.java:79)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
...
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:242)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
07-27 16:49:52.639 30449-31180/com.xxx.xxx D/Retrofit﹕ ---- END ERROR
My code:
public static RestAdapter createRestAdapter(String baseUrl, ApiRequestInterceptor interceptor, Gson gson) {
return new RestAdapter.Builder()
.setConverter(new GsonConverter(gson))
.setEndpoint(baseUrl)
.setClient(createClient())
.setRequestInterceptor(interceptor)
.setProfiler(interceptor)
.setErrorHandler(ApiException.ERROR_HANDLER)
.build();
}
public static Client createClient() {
if (isOkHttpEnabled()) {
if (isOkHttpTimeoutEnabled()) {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(15, TimeUnit.SECONDS);
client.setReadTimeout(15, TimeUnit.SECONDS);
client.setWriteTimeout(15, TimeUnit.SECONDS);
return new OkClient(client);
}
return new OkClient();
} else {
return new UrlConnectionClient();
}
}
Is this a bug or a legitimate timeout? Could you provide an executable test case that demonstrates the problem? There are a few tests in CallTest.java to get you started!
Sorry, I can't write that test case. It only appeared on that device.
I think the question is why does OkClient read timeout. The network and server is OK, other requests using AsyncHttpClient can work well.
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ ---> HTTP GET http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ Accept: application/json
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ User-Agent: XXX/1.1.0.3(beta) (App) Dalvik/1.6.0 (Linux; U; Android 4.4.4; MI 4LTE MIUI/V6.3.6.0.KXECNBL)
07-27 16:49:36.224 30449-31180/com.xxx.xxx D/Retrofit﹕ ---> END HTTP (no body)
07-27 16:49:52.615 30449-31180/com.xxx.xxx D/Retrofit﹕ ---- ERROR http://xxx.xxx.xxx.xxx/products/search
07-27 16:49:52.638 30449-31180/com.xxx.xxx D/Retrofit﹕ java.net.SocketTimeoutException
Related issue:
https://github.com/square/okhttp/issues/1518#issuecomment-87996760
This can fix it:
add
android:vmSafeMode="true"
in the Android configuration file
Hopefully this fixes it with Okio 1.6.0: https://github.com/square/okio/pull/164
Nice, fixed!
Still experience the issue with the following setup in build.gradle:
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0'
compile 'com.squareup.okio:okio:1.6.0'
android:vmSafeMode="true" didn't fix the issue
Still happens in okhttp 2.5.0 on my Lollipop device.
You don't need to comment on every issue.
On Thu, Oct 22, 2015 at 4:15 PM Igor Ganapolsky [email protected]
wrote:
Still happens in okhttp 2.5.0 on my Lollipop device.
—
Reply to this email directly or view it on GitHub
https://github.com/square/okhttp/issues/1771#issuecomment-150343889.
It's annoying. Those subscribed to these projects don't need to get 4
emails from you with the same thing.
On Thu, Oct 22, 2015 at 4:19 PM Igor Ganapolsky [email protected]
wrote:
Why not?
—
Reply to this email directly or view it on GitHub
https://github.com/square/okhttp/issues/1771#issuecomment-150344730.
This is still happening. I am using Retrofit 1.9.0 with OkHttp 2.6.0.
I am getting this error:
retrofit.RetrofitError
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:79)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:909)
at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:93)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:894)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:748)
at com.squareup.okhttp.Call.getResponse(Call.java:277)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:234)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:196)
at com.squareup.okhttp.Call.execute(Call.java:79)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
... 7 more
My guess is that this issue is related to dead sockets. Server closes connections and client has no way to figure out that the socket is closed. OkHttp writes to the socket, and tries to read from it, hence the SocketTimeoutException.
I am experiencing this a lot on a LG G2 device. After this a number of connections fails and after about a minute or two, it starts to work. (Maybe all the sockets in the pool are closed and renewed?).
I encountered this issue on other devices, like Nexus 5, too. Exactly as I described above.
I can assure you that this is not a network connection problem, as other apps work well when this is happening. Also I can ping the endpoint from Terminal Emulator when it is happening, but connections on the app continue to fail for about 1 minute.
I used OkHttp 2.4 and 2.5, too. This issue is with me for about 6 months!
@swankjesse If there is anything I can do (maybe more debugging with extra logs?) that can pinpoint the problem, just let me know.
@mblcdr What TLS version is your server using?
@IgorGanapolsky I suppose it is version 1. TLSv1/SSLv3.
Well I had the same problem with TLSv1.0. So that could be the root cause.
On Thu, Dec 3, 2015 at 4:57 PM, Hamid Moazzami [email protected]
wrote:
@IgorGanapolsky https://github.com/IgorGanapolsky I suppose it is
version 1. TLSv1/SSLv3.—
Reply to this email directly or view it on GitHub
https://github.com/square/okhttp/issues/1771#issuecomment-161797467.
@IgorGanapolsky Well, I don't think that's the problem. We have a test server with no ssl, and the issue is present there, too.
I'm also experiencing SocketTimeoutExceptions on read using OkClient. I haven't (but will try) UrlConnectionClient. No SSL on the server. We were unable to reproduce the problem with a separate API test client (not Android). Server is returning successful responses quickly so I'm not sure why the read hangs for so long (and eventually times out).
Nexus 5 - Android M
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.6.0'
I think this issue needs to be reopened.
I switched to UrlConnectionClient() a few days ago. The socket timeouts have been less frequent, but do occur. Is it possible that the problem (if there is one) may not be client related but something lower level?
java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:484)
at java.net.PlainSocketImpl.-wrap0(PlainSocketImpl.java)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
at com.android.okhttp.okio.Okio$2.read(Okio.java:135)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:788)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:73)
at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:38)
Maybe this problem is related to #2053 and also #2073
@mblcdr thanks for the references. Is there anything I can do to determine if my issue is related to connection leaking?
@bdiegel
Unfortunately I don't know. I guessed according to the circumstances.
UPDATE: my issue appears to be between with this particular device (Nexus 5- 6.0) and my 5 GHz WiFi (real timeouts). I have a dual band router and have no issue when connected to the 2.4.
Also, another Nexus 5 - 6.0 works just fine on the same 5G. Suppose it may have different WiFi hardware (did not confirm). I tried a few other devices now and they work fine also.
I'll be updating to 6.0.1 next and will see if that fixes anything for this device. Cheers!
I get the same exception. In my case, I turn on the airplane mode and then turn it off, and I get the timeout error.
using okhttp 2.7.0 on android 6.0.0 Nexus 5x x86 Emulator
Update: Just tested it my code on an actual device Motorola Moto X pure edition Marshmallow 6.0.0 and all looks good.
Hi guyz how can i use synchronous connection suing retrofit android
I solved that problem increasing writeTimeout.
OkHttpClient.Builder builder = new OkHttpClient().
builder.connectTimeout(5, TimeUnit.MINUTES);
writeTimeout(5, TimeUnit.MINUTES);
readTimeout(5, TimeUnit.MINUTES);
okHttpClient = builder.build();
I'm still experiencing the same issue with Retrofit 2.1.0 and OkHttp 3.3.0
Same here, issue still present.
mark
it's wired, when i use vpn on android device, it will be connect to the server and can send request and receive response but if i switch off vpn, all requests will be SocketTimeoutException. but i still can get request and response from server using postman tool.
it's wired, when i use vpn on android device, it will be connect to the server and can send request and receive response but if i switch off vpn, all requests will be
SocketTimeoutException. but i still can get request and response from server using postman tool.
I face with the same problem. Have yout fixed it?
@moshtagh i used caddy web server as reverse proxy and put my web service api behind that.
the reason why i used caddy because it will give you free auto https. yes, retrofit+ okhttp not worked until i enabled https on the server side thanks to the caddy.
Same error with com.squareup.retrofit2:retrofit:2.5.0
Solved with a sleep for old androids before the .build():
`private static OkHttpClient getNewHttpClient(int connectionTimeoutSec, int readTimeoutSec, int writeTimeoutSec) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
if (SdkInfo.isDebugBuild()){
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
}
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.cache(null)
.addInterceptor(interceptor)
.connectTimeout(connectionTimeoutSec, TimeUnit.SECONDS)
.writeTimeout(readTimeoutSec, TimeUnit.SECONDS)
.readTimeout(writeTimeoutSec, TimeUnit.SECONDS)
;
//builder = enableLetsEncryptRootCert(enableTls12OnPreLollipop(client)).build();
builder = enableTls12OnPreLollipop(builder);
builder = trustAllSslCerts(builder);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
//added this sleep for old android phones, without this sleep the OkHttpClient.Builder will ignore the connectTimeout
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return builder.build();
}`
Most helpful comment
it's wired, when i use vpn on android device, it will be connect to the server and can send request and receive response but if i switch off vpn, all requests will be
SocketTimeoutException. but i still can get request and response from server using postman tool.