diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Pipes-Safe v2.3.0
+# Pipes-Safe v2.3.1
 
 `pipes-safe` builds upon
 [the `pipes` library](https://github.com/Gabriel439/Haskell-Pipes-Library) to
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+# Version 2.3.1
+
+* Remove `MonadFail` constraints introduced in version 2.3.0
+* Implement `MonadFail` for `SafeT`
+
 # Version 2.3.0
 
 * BREAKING CHANGE: Support GHC 8.6.1
diff --git a/pipes-safe.cabal b/pipes-safe.cabal
--- a/pipes-safe.cabal
+++ b/pipes-safe.cabal
@@ -1,5 +1,5 @@
 Name: pipes-safe
-Version: 2.3.0
+Version: 2.3.1
 Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
diff --git a/src/Pipes/Safe.hs b/src/Pipes/Safe.hs
--- a/src/Pipes/Safe.hs
+++ b/src/Pipes/Safe.hs
@@ -148,7 +148,7 @@
 data Restore m = Unmasked | Masked (forall x . m x -> m x)
 
 liftMask
-    :: forall m a' a b' b r . (MonadIO m, MonadCatch m, MonadFail m)
+    :: forall m a' a b' b r . (MonadIO m, MonadCatch m)
     => (forall s . ((forall x . m x -> m x) -> m s) -> m s)
     -> ((forall x . Proxy a' a b' b m x -> Proxy a' a b' b m x)
         -> Proxy a' a b' b m r)
@@ -172,7 +172,9 @@
         unmask (Respond b  fb') = Respond b  (unmask . fb')
         unmask (M m)            = M $ do
             -- retrieve base's unmask and apply to merged action
-            Masked unmaskVariant <- liftIO $ readIORef ioref
+            unmaskVariant <- liftIO $ do
+                Masked unmaskVariant <- readIORef ioref
+                return unmaskVariant
             unmaskVariant (m >>= chunk >>= return . unmask)
         unmask (Pure q)         = Pure q
 
@@ -183,7 +185,7 @@
 
     loop $ k unmask
 
-instance (MonadMask m, MonadIO m, MonadFail m) => MonadMask (Proxy a' a b' b m) where
+instance (MonadMask m, MonadIO m) => MonadMask (Proxy a' a b' b m) where
     mask = liftMask mask
 
     uninterruptibleMask = liftMask uninterruptibleMask
@@ -217,9 +219,28 @@
     in the event of exceptions.
 -}
 newtype SafeT m r = SafeT { unSafeT :: R.ReaderT (IORef (Maybe (Finalizers m))) m r }
-    deriving (Functor, Applicative, Alternative, Monad, MonadPlus, MonadFix,
-              EC.MonadError e, SC.MonadState s, WC.MonadWriter w, CC.MonadCont,
-              MonadThrow, MonadCatch, MonadMask, MonadIO, B.MonadBase b)
+    deriving
+    ( Functor
+    , Applicative
+    , Alternative
+    , Monad
+-- The derived instance for `MonadFail` requires a `MonadFail` instance for
+-- `ReaderT` which is first available in `transformers-0.5.0.0`
+#if MIN_VERSION_transformers(0,5,0)
+    , MonadFail
+#endif
+    , MonadPlus
+    , MonadFix
+    , EC.MonadError e
+    , SC.MonadState s
+    , WC.MonadWriter w
+    , CC.MonadCont
+    , MonadThrow
+    , MonadCatch
+    , MonadMask
+    , MonadIO
+    , B.MonadBase b
+    )
 
 instance MonadTrans SafeT where
     lift m = SafeT (lift m)
@@ -332,7 +353,7 @@
                 Just (Finalizers n fs) ->
                     (Just $! Finalizers n (M.delete (unlock key) fs), ())
 
-instance (MonadSafe m, MonadFail m) => MonadSafe (Proxy a' a b' b m) where
+instance MonadSafe m => MonadSafe (Proxy a' a b' b m) where
     type Base (Proxy a' a b' b m) = Base m
     liftBase = lift . liftBase
     register = lift . register
diff --git a/src/Pipes/Safe/Prelude.hs b/src/Pipes/Safe/Prelude.hs
--- a/src/Pipes/Safe/Prelude.hs
+++ b/src/Pipes/Safe/Prelude.hs
@@ -12,7 +12,6 @@
     writeFile
     ) where
 
-import Control.Monad.Fail (MonadFail)
 import Control.Monad.IO.Class (MonadIO(liftIO))
 import Pipes (Producer', Consumer')
 import Pipes.Safe (bracket, MonadSafe)
@@ -35,13 +34,13 @@
 {-| Read lines from a file, automatically opening and closing the file as
     necessary
 -}
-readFile :: (MonadSafe m, MonadFail m) => FilePath -> Producer' String m ()
+readFile :: MonadSafe m => FilePath -> Producer' String m ()
 readFile file = withFile file IO.ReadMode P.fromHandle
 {-# INLINABLE readFile #-}
 
 {-| Write lines to a file, automatically opening and closing the file as
     necessary
 -}
-writeFile :: (MonadSafe m, MonadFail m) => FilePath -> Consumer' String m r
+writeFile :: MonadSafe m => FilePath -> Consumer' String m r
 writeFile file = withFile file IO.WriteMode P.toHandle
 {-# INLINABLE writeFile #-}
