Skip to content

x/net/http2: stream was reset: PROTOCOL_ERROR #31534

@sinhaashish

Description

@sinhaashish

What version of Go are you using (go version)?

$ go version
go version go1.12 linux/amd64

Does this issue reproduce with the latest release?

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ashish/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/ashish/code/go"
GOPROXY=""
GORACE=""
GOROOT="/home/ashish/.gimme/versions/go1.12.linux.amd64"
GOTMPDIR=""
GOTOOLDIR="/home/ashish/.gimme/versions/go1.12.linux.amd64/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/ashish/code/go/src/github.com/minio/minio-java/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build786486078=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I am using minio for Object storage. Minio is a golang project using go1.12 as the base go version.
The server is HTTP2 enabled. I use using minio java client which uses okhttp3 . when i try to store the object in a bucket in multi threaded mode i get okhttp3.internal.http2.StreamResetException: stream was reset: NO_ERROR.
Refer minio/minio#7501 .

okhttp3.OkHttpClient uses http2.0 by default which causes such issue.
If i forcefuly set the protocol to 1.1 ,it works fine.
Refer PR minio/minio-java#766.

I find there is some issue with Go1.12 or okhttp3 as i found this issue in the community.
Refer square/okhttp#3955
The only solution provided there was to revert to HTTP1_1 .

Setting the protocol to 1.1 is not the solution as i am not using the functionality of HTTP2.0 enabled server.

Raised the issue with okhhttp refer square/okhttp#4964
Below is the code which replicates the problem

import io.minio.MinioClient;
class PutObjectRunnable implements Runnable {
   MinioClient client;
   String bucketName;
   String filename;

   public PutObjectRunnable(MinioClient client, String bucketName, String filename) {
       this.client = client;
       this.bucketName = bucketName;
       this.filename = filename;
   }

   public void run() {
       StringBuffer traceBuffer = new StringBuffer();

       try {

           client.putObject(bucketName, filename, filename);

       } catch (Exception e) {
           System.err.print(traceBuffer.toString());
           e.printStackTrace();
       }
   }
}


public class ThreadedPutObject {
    public static void main(String args[]) throws Exception {
	try{
        MinioClient client = new MinioClient("https://play.min.io:9000", "Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", true);
        client.traceOn(System.out);
        long startTime = System.currentTimeMillis();
		 boolean found = minioClient.bucketExists("my-bucketname");
      if (found) {
        System.out.println("my-bucketname already exists");
      } else {
        // Create bucket 'my-bucketname'.
        minioClient.makeBucket("my-bucketname");
        System.out.println("my-bucketname is created successfully");
      }        
      Thread[] threads = new Thread[7];
      String[] location = new String[]{"<<PATH_TO_OBJECT_1>>",
                                       "<<PATH_TO_OBJECT_2>>",
                                       "<<PATH_TO_OBJECT_3>>",
                                       "<<PATH_TO_OBJECT_4>>",
                                       "<<PATH_TO_OBJECT_5>>",
                                       "<<PATH_TO_OBJECT_6>>",	
                                       "<<PATH_TO_OBJECT_7>>" };

      for (int i = 0; i < 7; i++) {
            PutObjectRunnable pr = new PutObjectRunnable(client, "my-bucketname",location[i] );
          threads[i] = new Thread(pr);
      }
      for (int i = 0; i < 7; i++) {
        threads[i].start();
      }
            // Waiting for threads to complete.
      for (int i = 0; i < 7; i++) {
         threads[i].join();
          System.out.println(i);
        }
        // All threads are completed.
        } catch (Exception e) {
            throw e;
        }
        System.out.println("uploaded");
    }
}


What did you expect to see?

Object should have been uploaded.

What did you see instead?

okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions