diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs
index e8ca5be686765ed0cac7b41c53a3c8cee45b6b6d..9a456258161e345352b67896d3d97aa3b0a97be1 100644
--- a/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs
+++ b/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs
@@ -162,6 +162,11 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
                     var buffer = result.Buffer;
                     try
                     {
+                        if (_bodyOutput.Aborted)
+                        {
+                            break;
+                        }
+
                         if (!buffer.IsEmpty)
                         {
                             await AsyncIO!.WriteAsync(buffer);
diff --git a/src/Servers/IIS/IIS/src/Core/OutputProducer.cs b/src/Servers/IIS/IIS/src/Core/OutputProducer.cs
index 8bf887d1b86adad32ec39ba5b0d01f9bfaef3afc..3b52dc8e284d9eb66c555e9ae88536e78dc6e317 100644
--- a/src/Servers/IIS/IIS/src/Core/OutputProducer.cs
+++ b/src/Servers/IIS/IIS/src/Core/OutputProducer.cs
@@ -13,9 +13,10 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
 {
     internal class OutputProducer
     {
-        // This locks access to _completed.
+        // This locks access to _completed and _aborted.
         private readonly object _contextLock = new object();
         private bool _completed;
+        private volatile bool _aborted;
 
         private readonly Pipe _pipe;
 
@@ -32,6 +33,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
         }
 
         public PipeReader Reader => _pipe.Reader;
+        
+        public bool Aborted => _aborted;
 
         public Task FlushAsync(CancellationToken cancellationToken)
         {
@@ -44,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
         {
             lock (_contextLock)
             {
-                if (_completed)
+                if (_completed || _aborted)
                 {
                     return;
                 }
@@ -58,12 +61,12 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
         {
             lock (_contextLock)
             {
-                if (_completed)
+                if (_completed || _aborted)
                 {
                     return;
                 }
 
-                _completed = true;
+                _aborted = true;
 
                 _pipe.Reader.CancelPendingRead();
                 _pipe.Writer.Complete();
@@ -74,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
         {
             lock (_contextLock)
             {
-                if (_completed)
+                if (_completed || _aborted)
                 {
                     return Task.CompletedTask;
                 }
diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs b/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs
index 1cec8d64149f9effac6c95c6b93c3aa553270973..9f8c1dbb6f9fdcd69356dfdaab34fb606d5e9c15 100644
--- a/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs
+++ b/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs
@@ -33,7 +33,6 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests
         }
 
         [ConditionalFact]
-        [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/31404")]
         public async Task ClosesAfterDataSent()
         {
             var bodyReceived = CreateTaskCompletionSource();