{"id":751,"date":"2026-09-15T06:57:30","date_gmt":"2026-09-15T06:57:30","guid":{"rendered":"https:\/\/windows-vps.org\/blog\/?p=751"},"modified":"2026-09-15T06:57:30","modified_gmt":"2026-09-15T06:57:30","slug":"dotnet-hosting-bundle-iis-setup","status":"publish","type":"post","link":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/","title":{"rendered":"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The ASP.NET Core Hosting Bundle installs three things: the .NET runtime, the ASP.NET Core shared framework, and the <code>AspNetCoreModuleV2<\/code> IIS module that reverse-proxies requests to the out-of-process Kestrel server. Most &#8220;it works locally but 500s on IIS&#8221; failures trace to one of those three being absent or mismatched.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install Order and Verification<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install the bundle <em>after<\/em> IIS, or the module registration step has no IIS to register with. If you install IIS later, repair the bundle. Then verify all three components independently rather than assuming:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># 1. runtimes present\ndotnet --list-runtimes\n\n# 2. module registered globally\nGet-WebGlobalModule | Where-Object { $_.Name -like 'AspNetCoreModule*' } |\n  Select-Object Name, Image\n\n# 3. handler present in the site's config\nGet-WebConfiguration -PSPath \"IIS:\\Sites\\MyApp\" -Filter \"system.webServer\/handlers\/*\" |\n  Where-Object { $_.Name -like 'aspNetCore' }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>dotnet --list-runtimes<\/code> must show a <code>Microsoft.AspNetCore.App<\/code> entry matching your target framework. A machine with only <code>Microsoft.NETCore.App<\/code> will fail every Core web app. If the module is missing, restart the Windows Process Activation Service \u2014 not just W3SVC:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>net stop was \/y\nnet start w3svc<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Application Pool and web.config<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Three settings in the app pool and one in <code>web.config<\/code> account for the bulk of configuration errors.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Setting<\/th><th>Required value<\/th><th>Consequence if wrong<\/th><\/tr><\/thead><tbody><tr><td>App pool .NET CLR version<\/td><td><strong>No Managed Code<\/strong><\/td><td>CLR load failures, module never loads<\/td><\/tr><tr><td>Pipeline mode<\/td><td>Integrated<\/td><td>Handler mapping failures<\/td><\/tr><tr><td>Identity<\/td><td>ApplicationPoolIdentity (default) or a low-privilege service account<\/td><td>File\/registry access errors, or excessive rights<\/td><\/tr><tr><td>32-bit applications<\/td><td><code>false<\/code> unless you have 32-bit native deps<\/td><td>Mixed-bitness load failures<\/td><\/tr><tr><td><code>web.config<\/code> hostingModel<\/td><td><code>inprocess<\/code> for performance, <code>outofprocess<\/code> for isolation<\/td><td>500.30 with inprocess\/outofprocess mismatch<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>Import-Module WebAdministration\nSet-ItemProperty \"IIS:\\AppPools\\MyApp\" managedRuntimeVersion \"\"\nSet-ItemProperty \"IIS:\\AppPools\\MyApp\" managedPipelineMode Integrated\nSet-ItemProperty \"IIS:\\AppPools\\MyApp\" enable32BitAppOnWin64 $false<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Reading 500.19 vs 500.30 Correctly<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">These are unrelated faults that get conflated constantly.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>500.19 \u2014 Configuration Error.<\/strong> IIS could not parse <code>web.config<\/code>. The response names the offending section. Root causes: a <code>&lt;system.webServer&gt;<\/code> section locked at server level, a duplicate section handler, or a 32\/64-bit module mismatch. The fix is almost always a missing <code>appcmd unlock config<\/code> or a duplicate module registration, not anything in your application.<\/li><li><strong>500.30 \u2014 In-Process Start Failure.<\/strong> The module loaded but the app failed to start. This is your application, not IIS. Read the actual exception from the Windows Application log or by running the app standalone against the same DLL \u2014 that is the fastest path to the real error.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code># surface the real .NET exception rather than the generic 500 page\nGet-WinEvent -LogName Application -MaxEvents 20 |\n  Where-Object ProviderName -like '*IIS AspNetCore Module*' |\n  Select-Object TimeCreated, Message | Format-List<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Enable stdout logging in <code>web.config<\/code> for an app that starts fine standalone but dies under IIS \u2014 it captures the startup exception to a file you can read without a debugger:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;aspNetCore processPath=\"dotnet\" arguments=\".\\MyApp.dll\" \n           stdoutLogEnabled=\"true\" stdoutLogFile=\".\\logs\\stdout\" hostingModel=\"inprocess\" \/&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create the <code>logs<\/code> folder yourself \u2014 the module will not create it, and a missing folder silently produces no log. Turn stdout logging off once resolved; it prevents log rotation and grows without bound.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deployment and Permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The app pool identity needs read and execute on the deployment folder and write access only where the application genuinely writes. Applying this correctly is the difference between a working deployment and a stream of 500.30s on first request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$acl = \"IIS AppPool\\MyApp\"\nicacls \"C:\\inetpub\\MyApp\" \/grant \"${acl}:(OI)(CI)(RX)\" \/T \/C\nicacls \"C:\\inetpub\\MyApp\\logs\" \/grant \"${acl}:(OI)(CI)(M)\" \/T \/C\nicacls \"C:\\inetpub\\MyApp\\App_Data\" \/grant \"${acl}:(OI)(CI)(M)\" \/T \/C<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Publish with Web Deploy or <code>dotnet publish<\/code>, then confirm the deployed target framework matches the installed runtime \u2014 a version skew between the build SDK and the server runtime produces startup failures that look like configuration problems. The deployment pipeline mechanics are covered in <a href=\"https:\/\/windows-vps.org\/blog\/hosting-aspnet-core-on-iis-dotnet8-setup\/\">our ASP.NET Core on IIS hosting guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checklist Before You Go Live<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li><code>dotnet --list-runtimes<\/code> shows the matching <code>Microsoft.AspNetCore.App<\/code> version.<\/li><li><code>AspNetCoreModuleV2<\/code> appears in <code>Get-WebGlobalModule<\/code>.<\/li><li>App pool set to No Managed Code, Integrated pipeline, 32-bit disabled.<\/li><li>App pool identity has RX on the site root, M on write paths only.<\/li><li><code>stdoutLogEnabled<\/code> is <code>false<\/code> in production.<\/li><li>HTTPS binding and HSTS configured \u2014 steps in <a href=\"https:\/\/windows-vps.org\/blog\/iis-https-setup-bindings-certificates\/\">our IIS HTTPS bindings and certificates walkthrough<\/a>.<\/li><li>Application Pool recycling configured so a recycle does not drop in-flight requests.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Hosting It<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A single low-traffic ASP.NET Core site is comfortable on 2 vCPU \/ 4 GB with NVMe storage. <a href=\"https:\/\/interserver.net\/r\/1067805?url=interserver.net\/vps\/windows-vps.html\" rel=\"noreferrer noopener sponsored\" target=\"_blank\">InterServer Windows VPS<\/a> supplies licensed Windows Server with full IIS control and no restricted handlers, and code <strong>TRYINTERSERVER<\/strong> brings the first month to $0.01. If your build pipeline needs hourly provisioning or you want the option of a licensed Windows image on fast NVMe, <a href=\"https:\/\/vultr.com\/?ref=9804308-9J\" rel=\"noreferrer noopener sponsored\" target=\"_blank\">Vultr<\/a> and <a href=\"https:\/\/www.awin1.com\/cread.php?awinmid=116629&amp;awinaffid=2520403\" rel=\"noreferrer noopener sponsored\" target=\"_blank\">Database Mart<\/a> are worth comparing.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Tuning the Reverse Proxy to Kestrel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The module forwards requests to Kestrel over a local loopback port. Two defaults are worth changing on a busy site: the request body limit, because IIS caps uploads at 30 MB regardless of your application&#8217;s own limits, and the shutdown timeout, because a graceful recycle needs long enough for in-flight requests to drain.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># raise the IIS-level upload cap to 100 MB\nSet-WebConfigurationProperty -PSPath \"IIS:\\Sites\\MyApp\" `\n  -Filter \"system.webServer\/security\/requestFiltering\/requestLimits\" `\n  -Name maxAllowedContentLength -Value 104857600\n\n# confirm the app pool shutdown timeout gives in-flight requests time to finish\nGet-ItemProperty \"IIS:\\AppPools\\MyApp\" |\n  Select-Object shutdownTimeLimit, startMode<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A mismatch between the IIS limit and your Kestrel <code>MaxRequestBodySize<\/code> produces confusing 413 responses \u2014 the request is rejected before your middleware ever sees it. Set the IIS limit slightly higher than the application limit and let the application produce the meaningful error. Recycling behaviour and overlap settings are covered in <a href=\"https:\/\/windows-vps.org\/blog\/iis-application-pool-recycling-best-practices\/\">our IIS application pool recycling guide<\/a>, which matters more for in-process hosting where a recycle restarts your managed code.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>The ASP.NET Core Hosting Bundle installs three things: the .NET runtime, the ASP.NET Core shared framework, and the AspNetCoreModuleV2 IIS module that reverse-proxies requests to the out-of-process Kestrel server. Most &#8220;it works locally but 500s on IIS&#8221; failures trace to one of those three being absent or mismatched. Install Order and Verification Install the bundle &#8230; <a title=\"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo\" class=\"read-more\" href=\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/\" aria-label=\"Read more about ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":1,"footnotes":""},"categories":[5],"tags":[],"class_list":["post-751","post","type-post","status-publish","format-standard","hentry","category-tutorials-guides"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo - Windows VPS Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo\" \/>\n<meta property=\"og:description\" content=\"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo\" \/>\n<meta property=\"og:url\" content=\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/\" \/>\n<meta property=\"og:site_name\" content=\"Windows VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-15T06:57:30+00:00\" \/>\n<meta name=\"author\" content=\"windows-vps\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"windows-vps\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/\",\"url\":\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/\",\"name\":\"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo - Windows VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\"},\"datePublished\":\"2026-09-15T06:57:30+00:00\",\"author\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58\"},\"breadcrumb\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/windows-vps.org\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\",\"url\":\"https:\/\/windows-vps.org\/blog\/\",\"name\":\"Windows VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/windows-vps.org\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58\",\"name\":\"windows-vps\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g\",\"caption\":\"windows-vps\"},\"sameAs\":[\"https:\/\/windows-vps.org\/blog\"],\"url\":\"https:\/\/windows-vps.org\/blog\/author\/myxiechengxuan\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo - Windows VPS Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/","og_locale":"en_US","og_type":"article","og_title":"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo","og_description":"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo","og_url":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/","og_site_name":"Windows VPS Blog","article_published_time":"2026-09-15T06:57:30+00:00","author":"windows-vps","twitter_card":"summary_large_image","twitter_misc":{"Written by":"windows-vps","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/","url":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/","name":"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo - Windows VPS Blog","isPartOf":{"@id":"https:\/\/windows-vps.org\/blog\/#website"},"datePublished":"2026-09-15T06:57:30+00:00","author":{"@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58"},"breadcrumb":{"@id":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/windows-vps.org\/blog\/dotnet-hosting-bundle-iis-setup\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/windows-vps.org\/blog\/"},{"@type":"ListItem","position":2,"name":"ASP.NET Core Hosting Bundle on IIS: Install, Verify, and Fix the 500.19 \/ 500.30 Duo"}]},{"@type":"WebSite","@id":"https:\/\/windows-vps.org\/blog\/#website","url":"https:\/\/windows-vps.org\/blog\/","name":"Windows VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/windows-vps.org\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58","name":"windows-vps","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g","caption":"windows-vps"},"sameAs":["https:\/\/windows-vps.org\/blog"],"url":"https:\/\/windows-vps.org\/blog\/author\/myxiechengxuan\/"}]}},"_links":{"self":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/751","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/comments?post=751"}],"version-history":[{"count":2,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/751\/revisions"}],"predecessor-version":[{"id":755,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/751\/revisions\/755"}],"wp:attachment":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/media?parent=751"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/categories?post=751"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/tags?post=751"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}