Description
Describe the bug
I am seeing the following exception with a minimal gRPC project (greeter server/client) on the 105th request:
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2ConnectionErrorException: HTTP/2 connection error (PROTOCOL_ERROR): Pseudo-header field found in request headers after regular header fields.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.ValidateHeader(Span`1 name, Span`1 value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.OnHeader(Span`1 name, Span`1 value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack.HPackDecoder.ProcessHeaderValue(IHttpHeadersHandler handler)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack.HPackDecoder.OnByte(Byte b, IHttpHeadersHandler handler)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack.HPackDecoder.Decode(ReadOnlySequence`1 data, Boolean endHeaders, IHttpHeadersHandler handler)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.DecodeHeadersAsync(Boolean endHeaders, ReadOnlySequence`1 payload)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.ProcessHeadersFrameAsync[TContext](IHttpApplication`1 application, ReadOnlySequence`1 payload)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.ProcessFrameAsync[TContext](IHttpApplication`1 application, ReadOnlySequence`1 payload)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
Looking at the request that fails in wireshark, I do not see any pseudo-header's after the regular headers, so the exception appears to be incorrect.
To Reproduce
Steps to reproduce the behavior:
I've created a repo with code to reproduce the issue: https://github.com/coryflucas/dotnet-grpc-issue-repro. This contains a sample server, an example Envoy configuration, and a simple client program to call the server in a loop.
- Download reproduction repo
docker-compose up server envoy
- this will build and start the server and envory containersdocker-compose up client
- this will build and start the client container (note: this should start and then crash)
Expected behavior
The client should not crash after 105 requests.
Additional context
Configuring Envoy to only use the connection 100 times seems to alleviate the issue. Also tried using different gRPC methods to see if the magic number of 105 was tied somehow to the size/shape of the request and that doesn't seem to matter.
Here is the wireshark capture:
grpc.pcapng.gz. Let me know if I can provide any more information.