diff --git a/jose.cabal b/jose.cabal
--- a/jose.cabal
+++ b/jose.cabal
@@ -1,5 +1,5 @@
 name:                jose
-version:             0.8.1.0
+version:             0.8.2.0
 synopsis:
   Javascript Object Signing and Encryption and JSON Web Token library
 description:
@@ -84,6 +84,9 @@
     , quickcheck-instances
     , x509 >= 1.4
     , vector
+
+  if impl(ghc<8)
+    build-depends: fail
 
   ghc-options:    -Wall
   hs-source-dirs: src
diff --git a/src/Crypto/JOSE/Header.hs b/src/Crypto/JOSE/Header.hs
--- a/src/Crypto/JOSE/Header.hs
+++ b/src/Crypto/JOSE/Header.hs
@@ -62,6 +62,7 @@
   ) where
 
 
+import qualified Control.Monad.Fail as Fail
 import Data.List.NonEmpty (NonEmpty)
 import Data.Monoid ((<>))
 import Data.Proxy (Proxy(..))
@@ -285,12 +286,12 @@
 
 
 critObjectParser
-  :: (Foldable t0, Foldable t1, Monad m)
+  :: (Foldable t0, Foldable t1, Fail.MonadFail m)
   => t0 T.Text -> t1 T.Text -> Object -> T.Text -> m T.Text
 critObjectParser reserved exts o s
-  | s `elem` reserved         = fail "crit key is reserved"
-  | s `notElem` exts          = fail "crit key is not understood"
-  | not (s `M.member` o)      = fail "crit key is not present in headers"
+  | s `elem` reserved         = Fail.fail "crit key is reserved"
+  | s `notElem` exts          = Fail.fail "crit key is not understood"
+  | not (s `M.member` o)      = Fail.fail "crit key is not present in headers"
   | otherwise                 = pure s
 
 -- | Parse a "crit" header param
@@ -302,7 +303,7 @@
 -- * any value in "crit" does not have a corresponding key in the object
 --
 parseCrit
-  :: (Foldable t0, Foldable t1, Traversable t2, Traversable t3, Monad m)
+  :: (Foldable t0, Foldable t1, Traversable t2, Traversable t3, Fail.MonadFail m)
   => t0 T.Text -- ^ reserved header parameters
   -> t1 T.Text -- ^ recognised extensions
   -> Object    -- ^ full header (union of protected and unprotected headers)
