3
votes

This is my first gRPC application. I'm attempting to invoke a server-streaming RPC call from a .NET 5 gRPC client (Grpc.Net.Client 2.35.0) which results in the following exception in my local development environment:

Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: Requesting HTTP version 2.0 with version policy RequestVersionOrHigher while HTTP/2 is not enabled."

This occurs whether or not the server application is running. Here is the code I'm using to make the call:

using var channel = GrpcChannel.ForAddress(@"http://localhost:5000");
var client = new AlgorithmRunner.AlgorithmRunnerClient(channel);
using var call = client.RunAlgorithm(new RunAlgorithmRequest());

while (await call.ResponseStream.MoveNext())
{

}

My understanding is that .NET 5 gRPC is supposed to have HTTP/2 enabled by default: why does the exception indicate that HTTP/2 is not enabled and how do I resolve it?

2

2 Answers

5
votes

After further investigation, this appears related to proxy settings on my machine related to my company's network setup. Specifically, I have the following environment variables defined:

http_proxy https_proxy

.NET populates the HttpClient DefaultProxy from these environment variables. My company proxy appears to be interfering with HTTP/2 (unsupported?), preventing gRPC from working correctly. The workaround for local development is to manually set the default proxy for the HttpClient before making the gRPC call:

HttpClient.DefaultProxy = new WebProxy();
                
using var channel = GrpcChannel.ForAddress(@"http://localhost:5000");
var client = new AlgorithmRunner.AlgorithmRunnerClient(channel);
using var call = client.RunAlgorithm(new RunAlgorithmRequest());

This may represent a general problem with using gRPC through certain types of proxies.

1
votes

I faced the same problem sitting behind a corporate proxy and receiving this error message

An exception of type 'Grpc.Core.RpcException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Status(StatusCode="Unavailable", Detail="Error starting gRPC call. HttpRequestException: Connection refused SocketException: Connection refused", DebugException="System.Net.Http.HttpRequestException: Connection refused

I fully agree that your suggested workaround with bypassing all proxy settings by overwriting the DefaultProxy is legit and functional.

A slightly better approach would be not to hard code a 'bypass all proxy statement' in your code and use instead the no_proxy environment variable. The purpose of this environment variable is to define a rule for excluding traffic destined to certain hosts

Solution

Activate the env. variable no_proxy for your development setup like

For linux

export no_proxy=localhost,127.0.0.1

For Dockerfile

ENV no_proxy=localhost,127.0.0.1

For a deep dive session about proxy environment variables

It is important when you start your gRPC client application, that you check what the value of the read in environment variables is, because gRPC uses the HttpClient class under the hood, which considers all proxy environment variables. If the no_proxy value is not set, it has not effect.

var noProxy = Environment.GetEnvironmentVariable("no_proxy");