diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,8 @@
+## 3.2.24
+
+* Fix HTTP2 unwanted GoAways on late WindowUpdate frames.
+  [#711](https://github.com/yesodweb/wai/pull/711)
+
 ## 3.2.23
 
 * Log real requsts when an app throws an error.
diff --git a/Network/Wai/Handler/Warp/HTTP2/Receiver.hs b/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
--- a/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
+++ b/Network/Wai/Handler/Warp/HTTP2/Receiver.hs
@@ -10,6 +10,7 @@
 import Control.Concurrent.STM
 import qualified Control.Exception as E
 import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as C8
 import Data.IORef
 import Network.HPACK
 import Network.HPACK.Token
@@ -162,15 +163,15 @@
                  Nothing
                    | isResponse streamId -> return Nothing
                    | otherwise           -> do
-                         when (ftyp `notElem` [FrameHeaders,FramePriority]) $
-                             E.throwIO $ ConnectionError ProtocolError "this frame is not allowed in an idel stream"
                          csid <- readIORef clientStreamId
-                         if streamId <= csid then
-                             if ftyp == FramePriority then
+                         if streamId <= csid then -- consider the stream closed
+                             if ftyp `elem` [FrameWindowUpdate, FrameRSTStream, FramePriority] then
                                  return Nothing -- will be ignored
                                else
                                  E.throwIO $ ConnectionError ProtocolError "stream identifier must not decrease"
-                           else do
+                           else do -- consider the stream idle
+                             when (ftyp `notElem` [FrameHeaders,FramePriority]) $
+                                 E.throwIO $ ConnectionError ProtocolError $ "this frame is not allowed in an idel stream: " `BS.append` C8.pack (show ftyp)
                              when (ftyp == FrameHeaders) $ do
                                  writeIORef clientStreamId streamId
                                  cnt <- readIORef concurrency
diff --git a/Network/Wai/Handler/Warp/Run.hs b/Network/Wai/Handler/Warp/Run.hs
--- a/Network/Wai/Handler/Warp/Run.hs
+++ b/Network/Wai/Handler/Warp/Run.hs
@@ -211,7 +211,12 @@
     -- First mask all exceptions in acceptLoop. This is necessary to
     -- ensure that no async exception is throw between the call to
     -- acceptNewConnection and the registering of connClose.
+    --
+    -- acceptLoop can be broken by closing the listing socket.
     void $ mask_ acceptLoop
+    -- In some cases, we want to stop Warp here without graceful shutdown.
+    -- So, async exceptions are allowed here.
+    -- That's why `finally` is not used.
     gracefulShutdown set counter
   where
     acceptLoop = do
diff --git a/warp.cabal b/warp.cabal
--- a/warp.cabal
+++ b/warp.cabal
@@ -1,5 +1,5 @@
 Name:                warp
-Version:             3.2.23
+Version:             3.2.24
 Synopsis:            A fast, light-weight web server for WAI applications.
 License:             MIT
 License-file:        LICENSE
