diff --git a/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs b/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs
index 6b392965696a2bcac15d50045e4ec9b884f54306..ebbfdc962b8ef8253b8a6d2d15a8ce2bafee10a3 100644
--- a/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs
+++ b/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs
@@ -254,7 +254,6 @@ internal partial class RequestContext : NativeRequestContext, IThreadPoolWorkIte
     {
         Response.StatusCode = status;
         Response.ContentLength = 0;
-        Dispose();
     }
 
     internal unsafe void Delegate(DelegationRule destination)
diff --git a/src/Servers/HttpSys/src/RequestProcessing/RequestContextOfT.cs b/src/Servers/HttpSys/src/RequestProcessing/RequestContextOfT.cs
index 016190fd3a47822563047c56b55ec7e3b6119016..6d7eecab820495a0187815d802df090c426a99e2 100644
--- a/src/Servers/HttpSys/src/RequestProcessing/RequestContextOfT.cs
+++ b/src/Servers/HttpSys/src/RequestProcessing/RequestContextOfT.cs
@@ -32,10 +32,12 @@ internal sealed partial class RequestContext<TContext> : RequestContext where TC
             if (messagePump.Stopping)
             {
                 SetFatalResponse(503);
+                Dispose();
                 return;
             }
 
             TContext? context = default;
+            Exception? applicationException = null;
             messagePump.IncrementOutstandingRequest();
             try
             {
@@ -49,16 +51,12 @@ internal sealed partial class RequestContext<TContext> : RequestContext where TC
                 {
                     await OnCompleted();
                 }
-                application.DisposeContext(context, null);
-                Dispose();
             }
             catch (Exception ex)
             {
+                applicationException = ex;
+
                 Log.RequestProcessError(Logger, ex);
-                if (context != null)
-                {
-                    application.DisposeContext(context, ex);
-                }
                 if (Response.HasStarted)
                 {
                     // Otherwise the default is Cancel = 0x8 (h2) or 0x010c (h3).
@@ -94,11 +92,18 @@ internal sealed partial class RequestContext<TContext> : RequestContext where TC
             }
             finally
             {
+                if (context != null)
+                {
+                    application.DisposeContext(context, applicationException);
+                }
+
                 if (messagePump.DecrementOutstandingRequest() == 0 && messagePump.Stopping)
                 {
                     Log.RequestsDrained(Logger);
                     messagePump.SetShutdownSignal();
                 }
+
+                Dispose();
             }
         }
         catch (Exception ex)
diff --git a/src/Servers/test/FunctionalTests/HelloWorldTest.cs b/src/Servers/test/FunctionalTests/HelloWorldTest.cs
index 23cdf5eee28fdc14aa61ce4804e3122195342c62..04a0384941f091edf33a1b62be014cca76cb6593 100644
--- a/src/Servers/test/FunctionalTests/HelloWorldTest.cs
+++ b/src/Servers/test/FunctionalTests/HelloWorldTest.cs
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using System.Net;
 using System.Threading.Tasks;
 using Microsoft.AspNetCore.Server.IntegrationTesting;
 using Microsoft.AspNetCore.Testing;
@@ -108,4 +109,56 @@ public class HelloWorldTests : LoggedTest
             }
         }
     }
+
+    public static TestMatrix SelfHostTestVariants
+        => TestMatrix.ForServers(ServerType.Kestrel, ServerType.HttpSys)
+            .WithTfms(Tfm.Default)
+            .WithApplicationTypes(ApplicationType.Portable)
+            .WithAllHostingModels()
+            .WithAllArchitectures();
+
+    [ConditionalTheory]
+    [MemberData(nameof(SelfHostTestVariants))]
+    public async Task ApplicationException(TestVariant variant)
+    {
+        var testName = $"ApplicationException_{variant.Server}_{variant.Tfm}_{variant.Architecture}_{variant.ApplicationType}";
+        using (StartLog(out var loggerFactory, LogLevel.Debug, testName))
+        {
+            var logger = loggerFactory.CreateLogger("ApplicationException");
+
+            var deploymentParameters = new DeploymentParameters(variant)
+            {
+                ApplicationPath = Helpers.GetApplicationPath()
+            };
+
+            var output = string.Empty;
+            using (var deployer = new SelfHostDeployer(deploymentParameters, loggerFactory))
+            {
+                deployer.ProcessOutputListener = (data) =>
+                {
+                    if (!string.IsNullOrWhiteSpace(data))
+                    {
+                        output += data + '\n';
+                    }
+                };
+
+                var deploymentResult = await deployer.DeployAsync();
+
+                // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
+                using (var response = await RetryHelper.RetryRequest(() =>
+                {
+                    return deploymentResult.HttpClient.GetAsync("/throwexception");
+                }, logger, deploymentResult.HostShutdownToken))
+                {
+                    Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
+
+                    var body = await response.Content.ReadAsStringAsync();
+                    Assert.Empty(body);
+                }
+            }
+            // Output should contain the ApplicationException and the 500 status code
+            Assert.Contains("System.ApplicationException: Application exception", output);
+            Assert.Contains("/throwexception - - - 500", output);
+        }
+    }
 }
diff --git a/src/Servers/testassets/ServerComparison.TestSites/Startup.cs b/src/Servers/testassets/ServerComparison.TestSites/Startup.cs
index 61e3e3b27ee61ccc55c9b12ae3a7714deddd7355..93ef6b8df89f58234e227e7357ca4dcdf5acc8b2 100644
--- a/src/Servers/testassets/ServerComparison.TestSites/Startup.cs
+++ b/src/Servers/testassets/ServerComparison.TestSites/Startup.cs
@@ -12,6 +12,14 @@ public class Startup
 {
     public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
     {
+        app.Map("/throwexception", subApp =>
+        {
+            subApp.Run(context =>
+            {
+                throw new ApplicationException("Application exception");
+            });
+        });
+
         app.Run(ctx =>
         {
             return ctx.Response.WriteAsync("Hello World " + RuntimeInformation.ProcessArchitecture);