grpc-web icon indicating copy to clipboard operation
grpc-web copied to clipboard

Response closed without grpc-status (Headers only)

Open kevinprotoss opened this issue 5 years ago • 9 comments

Versions of relevant software used 0.12.0 What happened Throw error every about 10 minutes: Response closed without grpc-status (Headers only) What you expected to happen No error here, just normal message How to reproduce it (as minimally and precisely as possible):

Full logs to relevant components

Anything else we need to know Server side: using grpc-node to push message every minute( long polling ) Proxy: using envoy to transport h2 stream Client side: angular app using generated stub

It's still unclear, whether this is an error from server, client or proxy side. I guess the grpc-status header might not be set for some kind of response. Maybe normal message or ping message. If someone knows more details about that, please help me.

kevinprotoss avatar Apr 09 '20 10:04 kevinprotoss

I imagine this could well be the connection between Envoy and your gRPC server timing out. I've seen messages like this when a browser client closes the page or something like that too. It's a generic "unexpected disconnection" message.

johanbrandhorst avatar Apr 09 '20 10:04 johanbrandhorst

I think so too, therefore I created another issue in the grpc-node repo. I'll take a further inspect on this problem. Maybe enable debug trace for three parts and take a look what happened.

kevinprotoss avatar Apr 09 '20 12:04 kevinprotoss

Hello guys, I am having this issue too, only when trying to run long polling streaming connections. Using envoy in front of plain Go grpc implementation. Do I have to use grpc-web?

turbopape avatar Dec 06 '20 17:12 turbopape

Hi, I meet this problem too. Because the buffer size is too large, can use less buffer size to avoid this problem.

luhuaei avatar Dec 22 '20 01:12 luhuaei

grpc-web-proxy: has read/write timout and migh close your longPolling connection by timeout. Relevant for all client-server streaming calls.

am0wa avatar Mar 15 '21 11:03 am0wa

In my case, the kubernetes Kong ingress controller doesnt seem to be sending the chunk chunkType === ChunkType.TRAILERS so during the onTransportEnd function, there was no grpc-status hence the same bailout message. The data was there however.

samelie avatar Sep 27 '21 00:09 samelie

I'm seeing the same error, but in the network tab of the dev tools the request has a header grpc-status with the status code. When I try to set a breakpoint and read the header, it's not there.

stephane-arista avatar Oct 01 '21 22:10 stephane-arista

After switching to the Contour + Envoy setup this error vanished.

samelie avatar Oct 02 '21 00:10 samelie

This happens when Envoy or grpcwebproxy timeout happens. For grpcwebproxy you can set timeout for your needs like bellow.

--server_http_max_write_timeout=3600s 
--server_http_max_read_timeout=3600s

BUT this does not resolve that connection gets closed. So you have to figure out how to reconnect when this happens.

If you are using RxJS as I do you can add retryWhen for subscription if error happens. For example, if you have code like this.something.subscribe(...) Add following logic before .subscribe

.pipe(retryWhen(errorObservable => {
  return errorObservable.pipe(
    switchMap(err => {
      if (err.statusCode == 2
        && err.statusMessage == "Response closed without grpc-status (Headers only)") {
        return of(err)
      }
      return throwError(err);
    })
  )
}))

This would reconnect automatically on receiving this error. Beware that "Response closed without grpc-status" is returned when server is down and "Response closed without grpc-status (Headers only)" is returned when server closed connection. So filtering only by statusCode (2 == Unknown) is not possible.

Complete example would be:

this.something
  .pipe(retryWhen(errorObservable => {
    return errorObservable.pipe(
      switchMap(err => {
        if (err.statusCode == 2
          && err.statusMessage == "Response closed without grpc-status (Headers only)") {
          return of(err)
        }
        return throwError(err);
      })
    )
  }))
  .subscribe(...)

Good luck!

kroksys avatar Oct 07 '21 13:10 kroksys