Posts Tagged ‘middleware’

Health middleware in AspnetCore, or rather Dotnet6 throws TaskCanceledException

January 21st, 2022

I added some health check to my aspnet site to trigger from Kubernetes startupProbe and sometimes got

{
	"EventId": 1,
	"LogLevel": "Error",
	"Category": "Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware",
	"Message": "An unhandled exception has occurred while executing the request.",
	"Exception": "System.Threading.Tasks.TaskCanceledException: A task was canceled.    
        at Microsoft.Extensions.Diagnostics.HealthChecks.DefaultHealthCheckService.CheckHealthAsync(Func`2 predicate, CancellationToken cancellationToken)    
        at Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckMiddleware.InvokeAsync(HttpContext httpContext)    
        at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)    
        at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)    
        at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)",
	"State": {
		"Message": "An unhandled exception has occurred while executing the request.",
		"{OriginalFormat}": "An unhandled exception has occurred while executing the request."
	}
}

There is nothing in my health checking code that can throw (famous last words…). In the stack above there is none of my code.

There might be a call to cancel that results in a TaskCanceledException or something with authentication/authorisation as can be seen in the stack.

To make a long story short I moved the calls to UseHealthCheck from below UseEndpoints to above UseAuthentication as my endpoints are anonymous (they are very lightweight).

app.UseRouting();

app.UseHealthChecks("/api/article/health/alive", new HealthCheckOptions
{
    Predicate = check => true
});
app.UseHealthChecks("/api/article/health/ready", new HealthCheckOptions
{
    Predicate = check => true
});
app.UseHealthChecks("/api/article/health/startup", new HealthCheckOptions
{
    Predicate = check => true
});

app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});