The global exception handler is rethrowing the BadHttpRequestException: Unexpected end of request content as unhandled exception

See original GitHub issue

My ASP .NET Core WebAPI application is getting some unidentified requests resulting in the below error.

Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Unexpected end of request content.

This error is getting logged only at the kestrel (stdout_logfile) and not in the application’s error log. Seems like the global exception handler is rethrowing the exception as unhandled exception.

As the request keeps coming, the application becomes slow and gets crashed, ended up in restarting the supervisor to bring up the application.

Error log:

^[[41m^[[30mfail^[[39m^[[22m^[[49m: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
      An unhandled exception has occurred while executing the request.
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Unexpected end of request content.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1ContentLengthMessageBody.ReadAsyncInternal(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 buffer, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool`1 bytePool, Nullable`1 limit, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.NewtonsoftJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
   at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
   at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   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)

Code

Exception Filtering code:

public void ConfigureServices(IServiceCollection services)
{
    ...
    ...

    services.AddControllers()
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressConsumesConstraintForFormFileParameters = true;
                options.SuppressInferBindingSourcesForParameters = true;
                options.SuppressModelStateInvalidFilter = true;
                options.SuppressMapClientErrors = true;
                options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
                    "https://httpstatuses.com/404";

                options.InvalidModelStateResponseFactory = context =>
                {
                    var result = new BadRequestObjectResult(context.ModelState);

                    // TODO: add `using System.Net.Mime;` to resolve MediaTypeNames
                    result.ContentTypes.Add(MediaTypeNames.Application.Json);
                    result.ContentTypes.Add(MediaTypeNames.Application.Xml);

                    return result;
                };
            });

        services.AddControllers(options =>
            options.Filters.Add(new HttpResponseExceptionFilter())
        );
        
    ...
    ...
}

Exception handler code:

public void OnActionExecuted(ActionExecutedContext context)
{
    if (context.Exception is HttpResponseException exception)
    {
        logger.Error(context.Exception);

        context.Result = new ObjectResult(exception.Value)
        {
            StatusCode = exception.Status,
        };

        context.ExceptionHandled = true;
    }

    else if (context.Exception is BadHttpRequestException badException)
    {
        logger.Error(context.Exception);

        context.Result = new ObjectResult(badException.Data.Values)
        {
            StatusCode = badException.StatusCode,
        };

        context.ExceptionHandled = true;
    }

    else if (context.Exception is Exception otherException)
    {
        logger.Error(context.Exception);

        context.Result = new ObjectResult(otherException.Data.Values)
        {
            StatusCode = otherException.HResult,
        };

        context.ExceptionHandled = true;
    }
}

Issue

Why is error not caught at the below global handler, or why is the error getting rethrown as unhandled exception. What am I doing wrong here?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
msftbot[bot]commented, Sep 25, 2020

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

0reactions
msftbot[bot]commented, Dec 8, 2021

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Seems like the global exception handler is rethrowing ...
Core.BadHttpRequestException: Unexpected end of request content. This error is getting logged only at the kestrel (stdout_logfile) and not in ...
Read more >
BadHttpRequest and Bad Performance from simple .NET ...
BadHttpRequestException : Unexpected end of request content. The above is the exception that is generated over and over again.
Read more >
ASP.NET Core global exception handling gotchas
Implementing an ASP.NET global exception handler is usually done for purposes such as: Translating exception types into HTTP status codes, ...
Read more >
Centralized exception handling and request validation in ...
Let's start with exception handling. ASP.NET Core exposes a feature called IExceptionHandlerFeature which you can use to globally handle ...
Read more >
BadHttpRequestException and Performance Problems in . ...
I am using EF with a MySQL database and anytime my API takes on more than 10+ requests at once, I start to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found