c-an
c-an

Reputation: 4090

OkHttp keeps getting StreamResetException: stream was reset: INTERNAL_ERROR when it's 200

I got StreamResetException: stream was reset: INTERNAL_ERROR from OkHttp. What's the problem?

Here's the logs.

I/okhttp.OkHttpClient: <-- 200 https://www.example.com/user/list (396ms)
I/okhttp.OkHttpClient: date: Fri, 04 Dec 2020 02:21:35 GMT
I/okhttp.OkHttpClient: content-type: application/json
I/okhttp.OkHttpClient: content-length: 99730
I/okhttp.OkHttpClient: server: nginx/1.18.0
I/okhttp.OkHttpClient: allow: GET, HEAD, OPTIONS
I/okhttp.OkHttpClient: x-frame-options: DENY
I/okhttp.OkHttpClient: x-content-type-options: nosniff
I/okhttp.OkHttpClient: referrer-policy: same-origin
D/okhttp.Http2: << 0x00000003  5792 DATA          
D/okhttp.Http2: << 0x00000003     4 RST_STREAM    
D/okhttp.TaskRunner: Q10092 canceled              : OkHttp ConnectionPool
D/force: okhttp3.internal.http2.StreamResetException: stream was reset: INTERNAL_ERROR
D/okhttp.Http2: >> 0x00000000     8 GOAWAY     
D/okhttp.TaskRunner: Q10096 finished run in 216 ms: OkHttp www.example.com

This is issued in Okhttp Gihub Repository. But any issues haven't solved yet.

I called the API like this

    @Headers("Content-Type: application/json")
    @GET("/user/list")
    fun getUserList(@Header("Authorization") jwt: String): Call<ArrayList<UserData>>

It's 200 but I get nothing. It's very weird behaviour..

Is it a server problem or my problem? (The server is Django).

Upvotes: 12

Views: 28839

Answers (5)

VicPls
VicPls

Reputation: 125

In my case the data from the stream completely was read but last call of function read() throws the exception. Workaround may be like this.

long fileSize = response.networkResponse().body().contentLength();

inputStream = body.byteStream();
outputStream = new FileOutputStream(forexChiefFile);
while (true) {
    int readQty;
    try {
        readQty = inputStream.read(readBuffer);
        if (readQty == -1) break;

    }catch (okhttp3.internal.http2.StreamResetException strRst){
        // work around of INTERNAL_ERROR
        if (fileSize == fileSizeDownloaded) break;
        else throw resetException;
    }
    outputStream.write(readBuffer, 0, readQty);
    
    fileSizeDownloaded += readQty;
    //Log.d(TAG, "readQty="+ readQty +";  Downloaded="+ fileSizeDownloaded);
    
}
outputStream.flush();

Upvotes: 0

Yuriy Zhilovets
Yuriy Zhilovets

Reputation: 430

The same error was shown while reading images from a remote server by coil library (that deep inside called OkHttp).

Header accept-encoding: identity made things work. Maybe OkHttp cannot correctly parse gzip encoding returned by nginx.

Upvotes: 1

Divyansh Jain
Divyansh Jain

Reputation: 378

StreamResetException: Error code is sent by a server to indicate a problem server-side. It can be due to Nginx buffer size issue can also happen if overload a single server with multiple requests

Upvotes: 3

c-an
c-an

Reputation: 4090

it was Nginx buffer size problem.

If you are using AWS EC2,

Go to /etc/nginx/default.d/server.conf

And set,

proxy_redirect off;
proxy_buffering off;

Upvotes: 7

Yuri Schimke
Yuri Schimke

Reputation: 13468

As suggested in OkHttp issue tracker, mostly likely this is a server error after the headers are sent.

https://github.com/square/okhttp/issues/3936

Typically error code is sent by a server to indicate a problem server-side. It could also happen if OkHttp’s stream reader crashes with an unexpected exception.

I'd suggest checking for server errors if you can, but you can see the Http2 frame from the server here

D/okhttp.Http2: << 0x00000003     4 RST_STREAM  

Upvotes: 3

Related Questions