Grpc-dotnet: How can I solve this unhandled exception "Error starting gRPC call: The SSL connection could not be established"?

Created on 26 Feb 2020  路  3Comments  路  Source: grpc/grpc-dotnet

On Ubuntu 18.04, I am trying the template project for gRPC in ASP.NET Core 3.1.101, following https://docs.microsoft.com/en-us/aspnet/core/tutorials/grpc/grpc-start?view=aspnetcore-3.1&tabs=visual-studio-code.

I created the service by

/home/t/$ dotnet new grpc -o GrpcGreeter

I run the gRPC service by

/home/t/GrpcGreeter$ dotnet dev-certs https --trust
Specify --help for a list of available options and commands.

/home/t/GrpcGreeter$ dotnet run
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /home/t/GrpcGreeter

I created the client following the link and run the client by

/home/t/rpcGreeterClient$ dotnet run
Unhandled exception. Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="Error starting gRPC call: The SSL connection could not be established, see inner exception.")
   at GrpcGreeterClient.Program.Main(String[] args) in /home/t/GrpcGreeterClient/Program.cs:line 15
   at GrpcGreeterClient.Program.<Main>(String[] args)

I was wondering why the exception? How can I make the service and client work together?

In the client, the Program.cs code mentioned in the exception was copied by me from the link above:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using GrpcGreeter;
using Grpc.Net.Client;
namespace GrpcGreeterClient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // The port number(5001) must match the port of the gRPC server.
            var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client =  new Greeter.GreeterClient(channel);
            var reply = await client.SayHelloAsync(
                              new HelloRequest { Name = "GreeterClient" });
            Console.WriteLine("Greeting: " + reply.Message);
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

In the service, appsettings.json's content is:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}
question

Most helpful comment

Hi

Your issue is most likely the server has an invalid certificate. You can configure the client to not throw an error to fix this error - https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.1#call-a-grpc-service-with-an-untrustedinvalid-certificate

If that isn't the problem then you can setup logging to get more information about the error - https://docs.microsoft.com/en-us/aspnet/core/grpc/diagnostics?view=aspnetcore-3.1#grpc-client-logging

If you're not able to fix this issue then add a copy of the logs to this issue and I'll re-open it.

All 3 comments

Hi

Your issue is most likely the server has an invalid certificate. You can configure the client to not throw an error to fix this error - https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.1#call-a-grpc-service-with-an-untrustedinvalid-certificate

If that isn't the problem then you can setup logging to get more information about the error - https://docs.microsoft.com/en-us/aspnet/core/grpc/diagnostics?view=aspnetcore-3.1#grpc-client-logging

If you're not able to fix this issue then add a copy of the logs to this issue and I'll re-open it.

add this snippet to your client Code

AppContext.SetSwitch(
"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

Something like this..............................

using System;
using System.Net.Http;
using System.Threading.Tasks;
using GrpcGreeter;
using Grpc.Net.Client;
namespace GrpcGreeterClient
{
class Program
{
static async Task Main(string[] args)
{
//this snippet tells the gRPC server that incoming/call from the client service is a trusted call
//and this would trick the server to allow and process the request

           AppContext.SetSwitch(
            "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

        // The port number(5001) must match the port of the gRPC server.
        var channel = GrpcChannel.ForAddress("https://localhost:5001");
        var client =  new Greeter.GreeterClient(channel);
        var reply = await client.SayHelloAsync(
                          new HelloRequest { Name = "GreeterClient" });
        Console.WriteLine("Greeting: " + reply.Message);
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
}

}

I had the same error.
"Authentication failed because the remote party has closed the transport stream."
"The SSL connection could not be established"

I tryed many SSL custom certificate solutions proposed on the web, still the same issue.
I had my gRPC server running in a Docker image (so it was "not the same" as the client machine), this is when I started having the SSL issue. Because when I run both on my host (localhost) machine everything worked fine.
What it worked for me was:
(no necessary SSL custom certificate; the "default dev certificate" selected automatically by the host machine was enough)

In the service, appsettings.json's I needed to add the "EndPoints:Https" section:

{
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    },
    "EndPoints": {
      "Https": {
        "Url": "https://*:5001"
      },
      "Http": {
        "Url": "http://*:5000"
      }
    }
  }
}

With that I stopped having the "Authentication failed because the remote party has closed the transport stream. The SSL connection could not be established" error.

Now I had an error coming from the client side:
"The remote certificate is invalid according to the validation procedure. The SSL connection could not be established"

With that I just needed to start the client like this:

    // Return "true" to allow certificates that are untrusted/invalid
    var httpHandler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback =
            HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
    };

    // The port number(5001) must match the port of the gRPC server.
    using var channel = GrpcChannel.ForAddress("https://localhost:5001",
        new GrpcChannelOptions { HttpHandler = httpHandler });

Those 2 changes solved my SSL issues.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JamesNK picture JamesNK  路  4Comments

JamesNK picture JamesNK  路  6Comments

JamesNK picture JamesNK  路  3Comments

JamesNK picture JamesNK  路  3Comments

dominikjeske picture dominikjeske  路  4Comments