ASP.NET – Maximum Request Length Exceeded

This one issue has turned out to be a lot more difficult and complicated than one would imagine it to be.  You’ll most likely run into this when you try to upload a file greater than 4 MB using ASP.NET.

ASP.NET

The first point of concern is the configuration/system.web/httpRuntime@maxRequestLength attribute.  This value defaults to 4096KB or 4MB.  If you happen to attempt to upload a file between 4 MB and  ~28.61 MB on IIS 7 or IIS 7.5 (I’ll get to this in a minute) or greater than 4 MB on IIS 6 or lower, you’ll see something like this:

Server Error in '/Test' Application.
Maximum request length exceeded.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Maximum request length exceeded.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[HttpException (0x80004005): Maximum request length exceeded.]
   System.Web.HttpRequest.GetEntireRawContent() +11342583
   System.Web.HttpRequest.GetMultipartContent() +221
   System.Web.HttpRequest.FillInFormCollection() +345
   System.Web.HttpRequest.get_Form() +137
   Microsoft.Web.Infrastructure.DynamicValidationHelper.<>c__DisplayClass12.b__e() +63
   Microsoft.Web.Infrastructure.DynamicValidationHelper.<>c__DisplayClass12.b__11() +20
   Microsoft.Web.Infrastructure.DynamicValidationHelper.DeferredCountArrayList.get_Count() +20
   System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) +34
   System.Web.HttpRequest.get_Form() +186
   System.Web.Mvc.FormValueProvider..ctor(ControllerContext controllerContext, IUnvalidatedRequestValues unvalidatedValues) +55
   System.Web.Mvc.FormValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +65
   System.Web.Mvc.<>c__DisplayClassc.b__7(ValueProviderFactory factory) +28
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +238
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +148
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +472
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
   System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext) +343
   System.Web.Mvc.ControllerBase.get_ValueProvider() +57
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +80
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +152
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +785360
   System.Web.Mvc.Controller.ExecuteCore() +159
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
   System.Web.Mvc.<>c__DisplayClassb.b__5() +62
   System.Web.Mvc.Async.<>c__DisplayClass1.b__0() +20
   System.Web.Mvc.<>c__DisplayClasse.b__d() +54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371

IIS 7 / IIS 7.5

Now, if you happen to upload a file greater than ~28.61 MB on IIS 7 or IIS 7.5, you’ll see something a little bit different.

Server Error in Application "DEFAULT WEB SITE/TEST"

Internet Information Services 7.5

Error Summary
HTTP Error 404.13 - Not Found
The request filtering module is configured to deny a request that exceeds the request content length.

Detailed Error Information
Module	        RequestFilteringModule
Notification	BeginRequest
Handler	        StaticFile
Error Code	    0x00000000
Requested URL	http://localhost:80/Test/Home/Post
Physical Path	D:\Users\rasmussa\Documents\Visual Studio 2010\Projects\MvcApplication2\MvcApplication2\Home\Post
Logon Method	Not yet determined
Logon User      Not yet determined

Most likely causes:
Request filtering is configured on the Web server to deny the request because the content length exceeds the configured value.

This little gem was added in IIS 7 and it’s called Request Filtering, and the settings for it live in the configuration/system.webServer/security/requestFiltering node of web.config.  There is an attribute called maxAllowedContentLength, which performs a similar function to the maxRequestLength setting for the ASP.NET HTTP runtime.  The maxAllowedContentLength attribute defaults to 30000000 bytes, or ~28.61 MB.

Note: The maxAllowedContentLength setting is specified in bytes, whereas the maxRequestLength setting is specified in kilobytes.

ASP.NET Solution

So, now that you get the “Maximum Request Length Exceeded” exception, what can you do about it?  As you can see from the stack trace above, at no point is it hitting any code that I’ve created; this exception is thrown before any page or action gets called.  That means I had to turn to the global.asax exception handler, or Application_Error().

When I was trying to figure this out for myself, I came across several solutions…

One had some hacks in it to determine what was in the stack trace and then redirect based on the existence of a method in the stack trace (yuck) a la StackTrace.Contains(“GetEntireRawContent”).  I think it’s relatively obvious why this doesn’t sound like a very good solution.

Another involved reading in the entire response and then redirecting the user after determining the content length of the request.  This method is less than ideal since you would then be giving malicious users free reign over your network connection.  Someone could intentionally upload several 50 GB files at the same time, and with this solution, your server would be forced to accept all of the content that user would be sending.  This could cause your server’s network connection to become saturated.

I came across a little bit more elegant of a solution…

.NET 4

protected void Application_Error()
{
    HttpException h = Server.GetLastError() as HttpException;

    if (h != null && h.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge) // System.Web.Management
    {
        Server.ClearError();
        Response.Redirect("~/Error/UploadTooLarge");
    }
}

All .NET Versions

private const string UPLOAD_TOO_LARGE = "Maximum request length exceeded.";

protected void Application_Error(object sender, EventArgs e)
{
    HttpException exception = Server.GetLastError() as HttpException;
    Exception innerException = (exception == null) ? null : exception.InnerException;

    if (innerException != null && innerException.Message == UPLOAD_TOO_LARGE)
    {
        Server.ClearError();
        Response.Redirect("~/Error/UploadTooLarge");
    }
}

This way, the ASP.NET HTTP runtime is still able to enforce the request limit, and the user will be redirected to an error page that informs them the size of their upload is too large.

IIS 7 / IIS 7.5 Solution

Fellow IIS 7 and 7.5 users, you are not out of the woods yet.  Actually, the solution for IIS 7 and 7.5 is even simpler than handling the HttpException from ASP.NET.  Do I hear you ask: “Oh really”?  Please read on…

Since the request filtering that was discussed earlier is a security feature built into IIS (not ASP.NET), it is executed before ASP.NET gets to throw any exceptions.  This is actually good news since it means we don’t need to write any code to handle the error.

First, you do need to make sure that the ASP.NET method of limiting the request length (maxRequestLength) is greater than or equal to the IIS method of limiting the request length (maxAllowedContentLength).  So, if you want to restrict uploads to 10MB, set maxRequestLength to “10240” (or greater) and maxAllowedContentLength to “10485760”.  Again, this essentially prevents the ASP.NET HTTP runtime from complaining about a request length that exceeds its limits, since the IIS feature will limit the length before ASP.NET has a chance to.

The specific status code, as you can see here, is 404.13 “Content Length Too Large”.  In the web.config, you can add an override to this particular status and sub-status to tell IIS to redirect this particular status to a certain page.

Add the following block to the configuration/system.webServer section of your web.config.

<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="13" />
  <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="/Error/UploadTooLarge" responseMode="Redirect" />
</httpErrors>

This configuration block will prevent IIS from displaying it’s default (read: user unfriendly) error page for 404.13, and allow you to redirect them to a more useful page that informs them they’ve uploaded a file that is too large.  Be advised that the path attribute of error is an absolute path (you can’t reference the application root using ~) when the responseMode is set to “Redirect”.

So, with all of the changes here, your web.config file would look something like this… (I’ve removed the standard web.config elements for brevity)

<configuration>
    <system.web>
        <httpRuntime maxRequestLength="10240" />
    </system.web>
 
    <system.webServer>
        <security>
            <requestFiltering>
                <requestLimits maxAllowedContentLength="10485760" />
            </requestFiltering>
        </security>
        <httpErrors errorMode="Custom" existingResponse="Replace">
            <remove statusCode="404" subStatusCode="13" />
            <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="/Error/UploadTooLarge" responseMode="Redirect" />
        </httpErrors>
    </system.webServer>
</configuration>

Tags: , , , , , ,

This entry was posted on Saturday, April 23rd, 2011 at 3:54 pm and is filed under ASP.NET. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

6 Responses to “ASP.NET – Maximum Request Length Exceeded”

KaeL July 21st, 2011 at 9:43 pm

Hi,

I would like to ask, I’m using .net 2.0, and HttpException.WebEventCode is not supported. Is there any alternative for this? I can’t go to IIS solutions.

Austin Rasmussen July 23rd, 2011 at 11:03 am

Hey Kael,

Nice catch. It didn’t dawn on me that the WebEventCode was a newly added property. I’ve updated the article to include an alternative solution, which doesn’t use the WebEventCode property, and does not involve changing IIS configurations.

It is a little less elegant, since we’re actually comparing the error message, but it works well.

Let me know how this works for you!

Spencer Smith January 6th, 2012 at 4:56 pm

Hey man, was creating a small app at work using a file uploader and this helped out quite a bit. Thanks!!!!!

Austin Rasmussen January 6th, 2012 at 5:13 pm

No problem Spencer. Glad it helped!

This was a really annoying problem when I ran into it too.

Gabbar Singh January 8th, 2013 at 2:59 pm

You are a life saver. I pulled my hair out due to this problem.

James Wierzba August 2nd, 2013 at 3:21 pm

Thank you!

Leave a Reply

You must be logged in to post a comment.