Uploading huge files
See original GitHub issueUnable to upload big file when using IIS hosting
A clear and concise description of what the bug is. When <aspNetCore hostingModel="outofprocess" /> and file size is greater then 2GB file upload is stucking and 502 Bad Gateway is returned
To Reproduce
- Download Sample app which is based on samples Upload files in ASP.NET Core with a slight modification to StreamingController to use FileStream instead of MemoryStream
- In the
appsettings.json
file set the path for stored files (StoredFilesPath). - Publish it to IIS
- Modify web.config to have
hostingModel="outofprocess"
and addrequestLimits maxAllowedContentLength="4294967295"
torequestFiltering
section
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<remove name="aspNetCore" />
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\SampleApp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="outofprocess" requestTimeout="00:02:00" />
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295" />
</requestFiltering>
</security>
</system.webServer>
</location>
</configuration>
- Navigate to
http://localhost/StreamedSingleFileUploadPhysical
choose file greater then 2GB and click Upload button
-
In a scenario when hosting using Kestrel Web Server everything is working as expected and I’m able to upload huge file (6GB)
-
With modification to run with
hostingModel="inprocess"
(Program.cs)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
//.UseKestrel(options => options.Limits.MaxRequestBodySize = null)
.UseIISIntegration();
;
});
and adding [DisableRequestSizeLimit]
attribute to the UploadPhysical()
endpoint I’m able to upload files up to 4 GB. However, when uploading files greater than 4GB I’m getting 413 Request Entity Too Large
response. Is it possible to upload really huge files with ASP.NET Core when hosting it in IIS?
Further technical details
❯ dotnet --info
.NET Core SDK (reflecting any global.json): Version: 3.0.100 Commit: 04339c3a26
Runtime Environment: OS Name: Windows OS Version: 10.0.18362 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\3.0.100\
Host (useful for support): Version: 3.0.0 Commit: 7d57652f33
.NET Core SDKs installed: 2.1.100 [C:\Program Files\dotnet\sdk] 2.1.101 [C:\Program Files\dotnet\sdk] 2.1.201 [C:\Program Files\dotnet\sdk] 2.1.202 [C:\Program Files\dotnet\sdk] 2.1.300 [C:\Program Files\dotnet\sdk] 2.1.403 [C:\Program Files\dotnet\sdk] 2.1.500 [C:\Program Files\dotnet\sdk] 2.1.502 [C:\Program Files\dotnet\sdk] 2.1.505 [C:\Program Files\dotnet\sdk] 2.1.507 [C:\Program Files\dotnet\sdk] 2.2.401 [C:\Program Files\dotnet\sdk] 3.0.100 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
After timeout exceeded following are from stdout_log:
dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[11] List of registered output formatters, in the following order: Microsoft.AspNetCore.Mvc.Formatters.HttpNoContentOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.StringOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.StreamOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[4] No information found on request to perform content negotiation. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[8] Attempting to select an output formatter without using a content type as no explicit content types were specified for the response. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[10] Attempting to select the first formatter in the output formatters list which can write the result. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[2] Selected output formatter ‘Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter’ and content type ‘application/json’ to write the response. info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1] Executing ObjectResult, writing value of type ‘Microsoft.AspNetCore.Mvc.SerializableError’. info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2] Executed action SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp) in 135935.2648ms info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1] Executed endpoint ‘SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp)’ info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 135989.30250000002ms 400 application/json; charset=utf-8 dbug: Microsoft.AspNetCore.Server.Kestrel[26] Connection id “0HLRD6A3O7L0O”, Request id “0HLRD6A3O7L0O:00000001”: done reading request body. dbug: Microsoft.AspNetCore.Server.Kestrel[2] Connection id “0HLRD6A3O7L0O” stopped. dbug: Microsoft.AspNetCore.Server.Kestrel[39] Connection id “0HLRD6A3O7L0P” accepted. dbug: Microsoft.AspNetCore.Server.Kestrel[1] Connection id “0HLRD6A3O7L0P” started. info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 POST http://localhost/Streaming/UploadPhysical multipart/form-data; boundary=--------------------------532290777779290238672096 2149435735 dbug: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[1] POST requests are not supported dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1001] 1 candidate(s) found for the request path ‘/Streaming/UploadPhysical’ dbug: Microsoft.AspNetCore.Routing.Matching.DfaMatcher[1005] Endpoint ‘SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp)’ with route pattern ‘{controller=Home}/{action=Index}/{id?}’ is valid for the request path ‘/Streaming/UploadPhysical’ dbug: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[1] Request matched endpoint ‘SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp)’ info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0] Executing endpoint ‘SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp)’ info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3] Route matched with {action = “UploadPhysical”, controller = “Streaming”, page = “”}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] UploadPhysical() on controller SampleApp.Controllers.StreamingController (SampleApp). dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[1] Execution plan of authorization filters (in the following order): None dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[1] Execution plan of resource filters (in the following order): Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.SaveTempDataFilter, SampleApp.Filters.DisableFormValueModelBindingAttribute dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[1] Execution plan of action filters (in the following order): Microsoft.AspNetCore.Mvc.Filters.ControllerActionFilter (Order: -2147483648), Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter (Order: -3000) dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[1] Execution plan of exception filters (in the following order): None dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[1] Execution plan of result filters (in the following order): Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.SaveTempDataFilter dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[1] Executing controller factory for controller SampleApp.Controllers.StreamingController (SampleApp) dbug: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2] Executed controller factory for controller SampleApp.Controllers.StreamingController (SampleApp) dbug: Microsoft.AspNetCore.Server.Kestrel[25] Connection id “0HLRD6A3O7L0P”, Request id “0HLRD6A3O7L0P:00000001”: started reading request body. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[4] Connection id “0HLRD6A3O7L0P” paused. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[5] Connection id “0HLRD6A3O7L0P” resumed. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[19] Connection id “0HLRD6A3O7L0P” reset. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7] Connection id “0HLRD6A3O7L0P” sending FIN because: “The client closed the connection.” dbug: Microsoft.AspNetCore.Server.Kestrel[10] Connection id “0HLRD6A3O7L0P” disconnecting. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[11] List of registered output formatters, in the following order: Microsoft.AspNetCore.Mvc.Formatters.HttpNoContentOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.StringOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.StreamOutputFormatter, Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[4] No information found on request to perform content negotiation. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[8] Attempting to select an output formatter without using a content type as no explicit content types were specified for the response. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[10] Attempting to select the first formatter in the output formatters list which can write the result. dbug: Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[2] Selected output formatter ‘Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter’ and content type ‘application/json’ to write the response. info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1] Executing ObjectResult, writing value of type ‘Microsoft.AspNetCore.Mvc.SerializableError’. info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2] Executed action SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp) in 137223.6736ms info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1] Executed endpoint ‘SampleApp.Controllers.StreamingController.UploadPhysical (SampleApp)’ info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 137227.7231ms 400 application/json; charset=utf-8 dbug: Microsoft.AspNetCore.Server.Kestrel[26] Connection id “0HLRD6A3O7L0P”, Request id “0HLRD6A3O7L0P:00000001”: done reading request body. dbug: Microsoft.AspNetCore.Server.Kestrel[2] Connection id “0HLRD6A3O7L0P” stopped.
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (8 by maintainers)
@davidfowl Thanks for reaching out. Fixed ideally would be across Microsoft technologies large files “just works” end-to-end. So IIS has a story for large files, ASP.NET Core/5 has a story for large files, and everything just works - and documentation accurately describes how to achieve this outcome. Indeed, fixed would mean there is nothing special about 2 GB vs. 10 GB vs. 1 TB. IIS has an archaic 32-bit integer for setting the size limit and so maxes out at 2 GB. Ideally, this parameter should be deprecated and replaced with a 64-bit long for setting the size limit. Ideally, also any limits in ASP.NET Core use 64-bit longs as well. In addition, ideally all of the machinery in ASP.NET core can smoothly handle large files.
Large files are commonplace in 2020 and so this is an important scenario. Moreover, the fact that this limit is driven by a 32-bit integer overflow feels really broken, especially in a 64-bit world.
We can try this workaround and hopefully this will work. But ideally Microsoft can fix the scenario of large files. Anything relating to large file transfer hits this and causes all sorts of issues.
Any help with this would be greatly appreciated by us and the ASP.NET community!
@davidfowl I think that is fair - but it is still highly worthwhile actually fixing IIS’s 2 GB limit. In a new major version of the OS, presumably there would be a new major version of IIS and so something could be done, but without necessarily breaking backward compatability. This is super broken in IIS and then at least this issue would be finally fixed after literally decades of not being fixed.
Is there any other functionality in request filtering that would be lost that cannot be replaced by an equivalent in ASP.NET Core? If so, hopefully at least the documentation could be holistic in describing how to turn off request filtering, what is lost, what settings to put into ASP.NET core to regain this functionality, etc. It does seem a little risky that the request filtering would be completely off and now things are only filtered on the .NET core side.