diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## Req 3.9.2
+
+* The test suite works with `aeson-2.x.x.x`.
+
 ## Req 3.9.1
 
 * Builds with GHC 9.0.
diff --git a/Network/HTTP/Req.hs b/Network/HTTP/Req.hs
--- a/Network/HTTP/Req.hs
+++ b/Network/HTTP/Req.hs
@@ -680,8 +680,8 @@
     -- | The retry policy to use for request retrying. By default 'def' is
     -- used (see 'RetryPolicyM').
     --
-    -- __Note__: signature of this function was changed in the version
-    -- /1.0.0/.
+    -- __Note__: signature of this function was changed to disallow 'IO' in
+    -- version /1.0.0/ and then changed back to its current form in /3.1.0/.
     --
     -- @since 0.3.0
     httpConfigRetryPolicy :: RetryPolicyM IO,
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,8 +6,6 @@
 [![Stackage LTS](http://stackage.org/package/req/badge/lts)](http://stackage.org/lts/package/req)
 ![CI](https://github.com/mrkkrp/req/workflows/CI/badge.svg?branch=master)
 
-* [Motivation and Req vs other libraries](#motivation-and-req-vs-other-libraries)
-* [Unsolved problems](#unsolved-problems)
 * [Related packages](#related-packages)
 * [Blog posts](#blog-posts)
 * [Contribution](#contribution)
diff --git a/httpbin-tests/Network/HTTP/ReqSpec.hs b/httpbin-tests/Network/HTTP/ReqSpec.hs
--- a/httpbin-tests/Network/HTTP/ReqSpec.hs
+++ b/httpbin-tests/Network/HTTP/ReqSpec.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RankNTypes #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
@@ -11,9 +12,10 @@
 import Control.Monad.Trans.Control
 import Data.Aeson (ToJSON (..), Value (..), object, (.=))
 import qualified Data.Aeson as A
+import qualified Data.Aeson.KeyMap as Aeson.KeyMap
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
-import qualified Data.HashMap.Strict as HM
+import Data.Functor.Identity (runIdentity)
 import Data.Proxy
 import Data.Text (Text)
 import qualified Data.Text as T
@@ -408,13 +410,13 @@
 -- | Remove “origin” field from JSON value. Origin may change, we don't want
 -- to depend on that.
 stripOrigin :: Value -> Value
-stripOrigin (Object m) = Object (HM.delete "origin" m)
+stripOrigin (Object m) = Object (Aeson.KeyMap.delete "origin" m)
 stripOrigin value = value
 
 -- | Remove funny headers that might break the tests.
 stripFunnyHeaders :: Value -> Value
 stripFunnyHeaders (Object m) =
-  let f (Object p) = Object $ HM.filterWithKey (\k _ -> k `elem` hs) p
+  let f (Object p) = Object $ Aeson.KeyMap.filterWithKey (\k _ -> k `elem` hs) p
       f value = value
       hs =
         [ "Content-Type",
@@ -424,7 +426,7 @@
           "Foo",
           "Baz"
         ]
-   in Object (HM.adjust f "headers" m)
+   in Object (runIdentity (Aeson.KeyMap.alterF (pure . fmap f) "headers" m))
 stripFunnyHeaders value = value
 
 -- | This is a complete test case that makes use of <https://httpbin.org> to
@@ -457,7 +459,7 @@
 
 -- | The empty JSON 'Object'.
 emptyObject :: Value
-emptyObject = Object HM.empty
+emptyObject = Object Aeson.KeyMap.empty
 
 -- | Get a rendered JSON value as 'Text'.
 reflectJSON :: ToJSON a => a -> Text
diff --git a/req.cabal b/req.cabal
--- a/req.cabal
+++ b/req.cabal
@@ -1,11 +1,11 @@
 cabal-version:   1.18
 name:            req
-version:         3.9.1
+version:         3.9.2
 license:         BSD3
 license-file:    LICENSE.md
 maintainer:      Mark Karpov <markkarpov92@gmail.com>
 author:          Mark Karpov <markkarpov92@gmail.com>
-tested-with:     ghc ==8.8.4 ghc ==8.10.4 ghc ==9.0.1
+tested-with:     ghc ==8.8.4 ghc ==8.10.5 ghc ==9.0.1
 homepage:        https://github.com/mrkkrp/req
 bug-reports:     https://github.com/mrkkrp/req/issues
 synopsis:        HTTP client library
@@ -33,8 +33,8 @@
     exposed-modules:  Network.HTTP.Req
     default-language: Haskell2010
     build-depends:
-        aeson >=0.9 && <1.6,
-        authenticate-oauth >=1.5 && <1.7,
+        aeson >=0.9 && <3,
+        authenticate-oauth >=1.5 && <1.8,
         base >=4.13 && <5.0,
         blaze-builder >=0.3 && <0.5,
         bytestring >=0.10.8 && <0.12,
@@ -48,10 +48,10 @@
         modern-uri >=0.3 && <0.4,
         monad-control >=1.0 && <1.1,
         mtl >=2.0 && <3.0,
-        retry >=0.8 && <0.9,
+        retry >=0.8 && <0.10,
         template-haskell >=2.14 && <2.18,
         text >=0.2 && <1.3,
-        time >=1.2 && <1.10,
+        time >=1.2 && <1.13,
         transformers >=0.4 && <0.6,
         transformers-base,
         unliftio-core >=0.1.1 && <0.3
@@ -76,7 +76,7 @@
     default-language: Haskell2010
     build-depends:
         QuickCheck >=2.7 && <3.0,
-        aeson >=0.9 && <1.6,
+        aeson >=0.9 && <3,
         base >=4.13 && <5.0,
         blaze-builder >=0.3 && <0.5,
         bytestring >=0.10.8 && <0.12,
@@ -88,10 +88,10 @@
         modern-uri >=0.3 && <0.4,
         mtl >=2.0 && <3.0,
         req,
-        retry >=0.8 && <0.9,
+        retry >=0.8 && <0.10,
         template-haskell >=2.14 && <2.18,
         text >=0.2 && <1.3,
-        time >=1.2 && <1.10
+        time >=1.2 && <1.13
 
     if flag(dev)
         ghc-options: -O0 -Wall -Werror
@@ -108,7 +108,7 @@
     default-language: Haskell2010
     build-depends:
         QuickCheck >=2.7 && <3.0,
-        aeson >=0.9 && <1.6,
+        aeson >=2 && <3,
         base >=4.13 && <5.0,
         bytestring >=0.10.8 && <0.12,
         hspec >=2.0 && <3.0,
@@ -117,8 +117,7 @@
         monad-control >=1.0 && <1.1,
         mtl >=2.0 && <3.0,
         req,
-        text >=0.2 && <1.3,
-        unordered-containers >=0.2.5 && <0.3
+        text >=0.2 && <1.3
 
     if flag(dev)
         ghc-options: -O0 -Wall -Werror
