Retrofit - Too many follow-up requests: 21
Asked Answered
S

6

33

I'm using retrofit to make requests.

I've got following error:

java.net.ProtocolException: Too many follow-up requests: 21

The code is like below:

private OkHttpClient httpClient;
private CookieManager cookieManager;

public <S> S createCookieService(Class<S> serviceClass) {
    httpClient.interceptors().clear();
    httpClient.setCookieHandler(cookieManager);
    Retrofit.Builder builder = new Retrofit
            .Builder()
            .client(httpClient)
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create());

    Retrofit retrofit = builder.client(httpClient).build();

    return retrofit.create(serviceClass);
}

And then I'm making requests:

example:

1) login

 @POST("/login")
 Call<User> login();

2) some request:

@GET("/request")
Call<PojoPojo> getPojo();

And I'm getting this error too many follow-up requests: 21.

Please help.

Savanna answered 1/2, 2016 at 13:56 Comment(4)
did you find any solution for this yet?Ieyasu
Yes, i did but some very important dude from facebook (Martijn Pieters) decided to delete link to answer. Good luck.Savanna
Why don't you just put up the answer here? Isn't that the whole point of SO?Niobium
This may happen due to an error on your Server sideRhomboid
S
27

Jake Wharton wrote:

This gets thrown (by OkHttp, not Retrofit) when there are more than 20 redirects when calling an endpoint. Usually this indicates a redirect cycle between two endpoints. Both Chrome and Firefox will also stop loading the request after this many redirects and fail the request.

You need to consult with your server team or endpoint documentation to ensure you are passing the correct data directly to the endpoint you want to call. No action for Retrofit to take here.

And rest of the thread is there: https://github.com/square/retrofit/issues/1561

Savanna answered 14/3, 2018 at 14:27 Comment(1)
This solution might be useful if you want to reduce the number of retries : #29457034Sacker
D
7

This also happen's when the token's header's key already exists and instead of replacing it with the new token as shown below:

response.request.newBuilder()
                .header("Authorization", token)
                .build()

you add the new token(a single key can have many values in the headers), what's common in a lot of questions is add the token like this:

response.request.newBuilder()
                .addHeader("Authorization", token)
                .build()

This will result the request failing again(401) and you'll end up in a loop.

TL;DR: The correct way of setting a new token is:

response.request.newBuilder()
                    .header("Authorization", token)
                    .build()
Dissatisfy answered 20/8, 2020 at 19:33 Comment(0)
S
5

As a workaround, it is possible to use:

new OkHttpClient.Builder()
    .followRedirects(false)
    .followSslRedirects(false)

Nice to take a look at okhttp3.internal.http.RetryAndFollowUpInterceptor class source code.

I'm using version 3.12.0 of OkHttp.

Surgy answered 23/12, 2019 at 8:32 Comment(0)
T
4

For me the issue was: the request url was starting with "/".
Replace url @GET("/request") with @GET("request")

  • also the base url of the api should end with "/"
  • if using an Authorization header check if you need to set the value as "Bearer " + token instead

using retrofit 2.4.0 version:

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>retrofit</artifactId>
    <version>2.4.0</version>
</dependency>
Talton answered 25/4, 2018 at 7:23 Comment(0)
J
1

In okHttpClient,in the interceptor if your using authenticator, remove that authenticator. It Sets the authenticator used to respond to challenges from origin servers. It Uses [proxyAuthenticator] to set the authenticator for proxy servers.

Jointress answered 19/9, 2022 at 11:3 Comment(0)
H
0

In my case it was happening because of the cookie in header was expired. It is clear that we need to fix this in server side code but in case we can't change server side code we can use this workaround.

Following is the workaround which worked for me

catch (ProtocolException e) {
        
        Timber.w(e);
        if (e.getMessage().contains("Too many follow-up requests")) {
            doSynchronousLogin();

            Request.Builder builder = chain.request().newBuilder();
            builder.addHeader("Cookie", dataManager.getCookie());
            Timber.w("Request processed after auto-login");
            return chain.proceed(builder.build());
        }
    }

Above code is added in a retrofit interceptor

Histoplasmosis answered 29/6, 2021 at 6:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.