Dan Champagne
Dan Champagne

Reputation: 920

.NET Core Healthchecks UI not showing

I'm using .NET Core 3.1 and trying to set up health checks and running into an odd issue and need some help.

When I go to the basic health check URL (https://localhost:5001/hc), I get the following:

{
  "status": "Healthy",
  "errors": [
    {
      "key": "AssessmentContext",
      "value": "Healthy"
    }
  ]
}

Which looks good! However, when I try and go to the UI, it's saying that the application is unhealthy.

UI error

So it's pulling the endpoint name correctly, but it's not registering it right.

My startup.cs file looks like this:

public void ConfigureServices(IServiceCollection services) {
    ...

    services
        .AddHealthChecks()
        .AddDbContextCheck<AssessmentContext>();

    services.AddHealthChecksUI(opt => {
        opt.SetEvaluationTimeInSeconds(30);
        opt.MaximumHistoryEntriesPerEndpoint(60);

        opt.AddHealthCheckEndpoint(name: "app", uri: "~/hc");
    }).AddInMemoryStorage();

}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
    ...

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/hc", new HealthCheckOptions
        {
            Predicate = _ => true,
            ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse,
        });

        endpoints.MapHealthChecksUI(opt => {
            opt.UseRelativeApiPath = false;
            opt.UseRelativeResourcesPath = false;
            opt.AsideMenuOpened = false;

            opt.UIPath = "/health";
            opt.ApiPath = "/healthAPI";
        });


        ...
    });
}

And the csproj file has these version:

<PackageReference Include="AspNetCore.HealthChecks.UI" Version="3.1.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="3.1.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="3.1.1" />
<PackageReference Include="AspNetCore.HealthChecks.System" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="3.1.8" />
<PackageReference Include="AspNetCore.HealthChecks.MySql" Version="3.1.1" />

HealthChecks.UI.Core.HostedService.HealthCheckReportCollector: Error: GetHealthReport threw an exception when trying to get report from ~/hc configured with name app.

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
   at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)
   at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at HealthChecks.UI.Core.HostedService.HealthCheckReportCollector.GetHealthReport(HealthCheckConfiguration configuration)

Upvotes: 4

Views: 11893

Answers (2)

Gabriel Silva
Gabriel Silva

Reputation: 73

I encountered the following error during local development: "SSL connection could not be established."

After some research, I found a helpful solution from Omer on Stack Overflow (link here: net::ERR_CERT_AUTHORITY_INVALID in ASP.NET Core).

Here’s the sequence of commands that worked for me:

dotnet user-secrets clear
dotnet dev-certs https --clean
dotnet dev-certs https
dotnet dev-certs https --check --trust

This resolved the issue for me. I hope it helps anyone else facing the same problem!

Best,

Gabriel Gonçalves da Silva

Upvotes: 0

davidterra
davidterra

Reputation: 351

I am hopeful that you have already found the solution. But as the question is still unanswered and it was also a problem that I faced I will post how I solved it in the hope of helping others in the future. Thank you.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHealthChecks()
            .AddCheck("Products", new SqlServerHealthCheck(connectionString))
            .AddSqlServer(connectionString, name: "DataBase");
            
    services.AddHealthChecksUI(setup =>
    {
        setup.UseApiEndpointHttpMessageHandler(sp =>
        {
            return new HttpClientHandler
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => { return true; }
            };
        });
    }).AddInMemoryStorage();
}        

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider)
{
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapHealthChecks("/api/hc", new HealthCheckOptions
        {
            Predicate = _ => true,
            ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
        });
        endpoints.MapHealthChecksUI();
        
    });
}

Upvotes: 14

Related Questions