Okhttp: Retrofit 2.0.1 + okhttp 3.2.0: GET not working when connected to WiFi network (SocketTimeoutException)

Created on 28 Apr 2016  路  22Comments  路  Source: square/okhttp

I've found what appears to be a bug when performing a GET request to a private API. What is peculiar about this issue is the fact that even though it sometimes occurs when the Android device is connected to the mobile data network (around 10% of the time), on WiFi it just will never work, under any circumstance.

I've tested the same GET request using Postman, the private API's swagger interface, and on iOS (AFNetworking), but when trying to get the Android app to perform the exact same request using Retrofit and okhttp, it fails to complete the request.

The response is JSON-formatted, and I'm using a GsonBuilder to deserialize it and turn it into a list of Java entity objects, as one would normally do. The response body is turned into a JsonReader through the GsonBuilder, which is then looped through using the hasNext() method, which in turn throws an IOException in the form of a SocketTimeoutException when waiting for the server to continue submitting data - this is done library-side. It looks like the serializer is able to serialize the first pack of data correctly, but the second one never arrives and that causes a peek() method to throw the exception.

I'm currently intercepting the request and response which show the following info (I've removed the address since it's a private API I'm sending it to):

ApiManager: Sending request ******* on null

ApiManager: Received response for *******
Server: nginx/1.6.2
Vary: Accept, Cookie
Cache-Control: max-age=600
Content-Type: application/json
Date: Thu, 28 Apr 2016 20:36:37 GMT
Expires: Thu, 28 Apr 2016 20:42:57 GMT
Transfer-Encoding: chunked
Connection: Keep-Alive
Allow: GET, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Last-Modified: Thu, 28 Apr 2016 20:32:57 GMT
OkHttp-Sent-Millis: 1461875797821
OkHttp-Received-Millis: 1461875798035

Here's what I believe to be the relevant part of the code:

    @GET(ApiConstants.ENDPOINT)
    Call<List<Entity>> getEntityList();


    ...

    public ApiManager( .... ) {

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(
                    new Interceptor() {
                        @Override
                        public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
                            Request request = chain.request();

                            request = request.newBuilder()
                                    .addHeader(ApiConstants.AUTH_HEADER, ApiConstants.AUTH_VALUE)
                                    .build();
                            okhttp3.Response response = chain.proceed(request);

                            return response;
                        }
                    })
                .build();

        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Entity.class, new EntityDeserializer())
                .create();

        mRetrofitClient = new Retrofit.Builder()
                .baseUrl(ApiConstants.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        mApiService = mRetrofitClient.create(ApiInterface.class);

   ......

 mApiManager.getService().getEntityList().enqueue(new Callback<List<Entity>>() {
            @Override
            public void onResponse(Call<List<Entity>> call, Response<List<Entity>> response) {
               //Success
            }

            @Override
            public void onFailure(Call<List<Entity>> call, Throwable t) {
               //Always falls here on WiFi, gets SocketTimeoutException.
            }
        });

Finally, here's the exception:

> 04-28 14:50:50.432 3463-3463/com.package.dev W/System.err: java.net.SocketTimeoutException: timeout
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.Okio$3.newTimeoutException(Okio.java:212)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.AsyncTimeout.exit(AsyncTimeout.java:288)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.AsyncTimeout$2.read(AsyncTimeout.java:242)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.RealBufferedSource.read(RealBufferedSource.java:45)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okhttp3.internal.http.Http1xStream$ChunkedSource.read(Http1xStream.java:426)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.RealBufferedSource.read(RealBufferedSource.java:45)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.ForwardingSource.read(ForwardingSource.java:35)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at retrofit2.OkHttpCall$ExceptionCatchingRequestBody$1.read(OkHttpCall.java:279)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at okio.RealBufferedSource$1.read(RealBufferedSource.java:367)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at java.io.InputStreamReader.read(InputStreamReader.java:233)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1293)
> 04-28 14:50:50.435 3463-3463/com.package.dev W/System.err:     at com.google.gson.stream.JsonReader.peekKeyword(JsonReader.java:626)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:583)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.stream.JsonReader.peek(JsonReader.java:429)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:720)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:743)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.TypeAdapters$29.read(TypeAdapters.java:718)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.Streams.parse(Streams.java:48)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:54)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:106)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err:     at java.lang.Thread.run(Thread.java:818)
> 04-28 14:50:50.436 3463-3463/com.package.dev W/System.err: Caused by: java.net.SocketTimeoutException
> 04-28 14:50:50.439 3463-3463/com.package.dev W/System.err:     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:484)
> 04-28 14:50:50.439 3463-3463/com.package.dev W/System.err:     at java.net.PlainSocketImpl.-wrap0(PlainSocketImpl.java)
> 04-28 14:50:50.439 3463-3463/com.package.dev W/System.err:     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
> 04-28 14:50:50.439 3463-3463/com.package.dev W/System.err:     at okio.Okio$2.read(Okio.java:140)
> 04-28 14:50:50.439 3463-3463/com.package.dev W/System.err:     at okio.AsyncTimeout$2.read(AsyncTimeout.java:238)
> 04-28 14:50:50.439 3463-3463/com.package.dev W/System.err:    ... 31 more

Best case scenario, I've done something obviously wrong and you guys will point me in the right direction. If not, I'd appreciate any workarounds or potential ways to debug this issue and eventually resolve it. I've been doing some reading, and it seems to me like this is not a necessarily new thing, but from what I can see similar reports belong to previous versions of the library, and proposed fixes seem arbitrary and not well substantiated.

One of these, for example, involved disabling the tcp_timestamp parameter in the sysctl file on the server. However, I have no access to the file or the server and I'm not going to approach them without an explanation on why that would solve the issue. I'm mentioning it here because hopefully someone will be knowledgeable enough to tell me if that's a good solution/thing to try and why, so I can try that, but I'm crossing my fingers that won't be necessary.

Thanks for the attention. I can happily provide any more info if needed.

Most helpful comment

@Fireblend Hi, Even i facing the similar issue . One of the api's doesn't fetch me the result and throw socketTimeout exception. Could you solve the issue? Any help would be appriciated

All 22 comments

This doesn鈥檛 seem to be an OkHttp issue. It鈥檚 more like an issue with your network. Ie. I don't know if there鈥檚 anything we鈥檒l be able to do to help.

Sure, partly it could be attributed to how the network is setup, but even if that's the case, it'd point towards a set of conditions that for some reason cause OkHttp to behave erroneously when other software packages on multiple platforms don't. Wouldn't that still be of interest and worth looking into?

Yeah! We always want to be more resilient.

Is there any information in particular I could provide or anything I should look into that could help me track down the source of this issue? I plan to check if the issue occurs exclusively in this single WiFi network or if it's more widespread issue as I haven't had the chance to do so yet. Let me know if there's any sort of data collection I could do to help track it down.

If you figure out what OkHttp is doing differently, that would be a first step.

I鈥檓 going to close this because there鈥檚 no obvious next step for us to take. If you can figure out what OkHttp is doing differently we can reopen this.

@Fireblend Hi, Even i facing the similar issue . One of the api's doesn't fetch me the result and throw socketTimeout exception. Could you solve the issue? Any help would be appriciated

Hi, Even i facing the same issue any help would be appriciated

The same

Same Problem

same problem

Same problem !!!

Same problem

I am facing the same problem but in my case working with wifi but not working with mobile data. This is not a good thing. I have completed a project but stuck with this issue... Please need support badly... reopen this issue

Same problem here. I have a 2-step login with Facebook, Facebook logs in OK, but when connecting to my server, even with a large timeout value, I get a SocketTimeOutException when connected via Wi-Fi.
It looks like something's wrong here, actually. Otherwise I wouldn't be able to explain how other clients are reaching their destinations and okhttp is not, on the same 30 second-timeframe, same device, same Wi-Fi network.

I am facing the same problem retrofit working with wifi but not with mobile data

Same problem, 95% of phones work most of the time, 5% of phones sometimes not work.

I got the issue : <-- HTTP FAILED: java.net.SocketTimeoutException: timeout, I am using retrofit 2.6.0
implementation('com.squareup.retrofit2:retrofit:2.6.0')

W/System.err: java.net.SocketTimeoutException: timeout
D/OkHttp: <-- HTTP FAILED: java.net.SocketTimeoutException: timeout
W/System.err: at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.java:656)
W/System.err: at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.java:664)
W/System.err: at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.java:153)
W/System.err: at okhttp3.internal.http2.Http2Codec.readResponseHeaders(Http2Codec.java:131)
W/System.err: at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err: at com.heitouyang.promise.retrofit.HeaderInterceptor.intercept(HeaderInterceptor.java:35)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
D/OkHttp: <-- HTTP FAILED: java.net.SocketTimeoutException: timeout
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:12
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err: at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:213)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
W/System.err: at java.lang.Thread.run(Thread.java:764)

Same problem

I have the same problem.
my android app, connected with wifi, give me lot of timeout.
i switch to mobile data, every thing ok
and back to wifi, now it's work fine

Same Problem

Was this page helpful?
0 / 5 - 0 ratings