diff --git a/NetSNMP.cabal b/NetSNMP.cabal
--- a/NetSNMP.cabal
+++ b/NetSNMP.cabal
@@ -1,24 +1,25 @@
 name:                 NetSNMP
-version:              0.3.2.5
+version:              0.4.0.0
 synopsis:             Bindings for net-snmp's C API for clients
 description:          Network.Protocol.NetSNMP is a partial binding to the
-                      library portion of the net-snmp package.  It uses the
+                      library portion of the net-snmp package. It uses the
                       'single-session api', which is claimed to be
                       thread-safe.  Not all operations are supported yet;
                       please contact the maintainer if you're in need of
                       expanded functionality, and especially if you would
                       like to contribute.
 category:             Network
-cabal-version:        >= 1.8
+cabal-version:        1.12
 license:              BSD3
 license-file:         license
-author:               Pavlo Kerestey and Humane Software for Global Access Internet Services GmbH
+author:               See authors
 maintainer:           Pavlo Kerestey <pavlo@kerestey.net>
 build-type:           Simple
 homepage:             https://github.com/ptek/netsnmp
 bug-reports:          https://github.com/ptek/netsnmp/issues
 extra-source-files:   changes
 
+
 source-repository head
   type:               git
   location:           git@github.com:ptek/netsnmp.git
@@ -27,20 +28,23 @@
   hs-source-dirs:     src
   build-tools:        hsc2hs
   exposed-modules:    Network.Protocol.NetSNMP
-  extensions:         ForeignFunctionInterface, CPP, EmptyDataDecls
+  default-extensions: ForeignFunctionInterface, CPP, EmptyDataDecls
   extra-libraries:    netsnmp
   ghc-options:        -Wall -static -fno-warn-missing-signatures -fno-warn-unused-binds
+  default-language:   Haskell2010
   build-depends:      base >=4.5 && <5
-                     ,bytestring >= 0.9 && < 0.11
+                     ,bytestring >= 0.9 && < 0.12
 
+
 test-suite tests
   hs-source-dirs:     tests
-  extensions:         OverloadedStrings
+  default-extensions: OverloadedStrings
   ghc-options:        -Wall -static -threaded -fno-warn-missing-signatures -fno-warn-unused-binds -fno-warn-unused-do-bind
   type:               exitcode-stdio-1.0
   main-is:            RunTests.hs
+  default-language:   Haskell2010
   build-depends:      base >= 4.5 && <5
-                     ,bytestring >= 0.9 && < 0.11
+                     ,bytestring >= 0.9 && < 0.12
                      ,HUnit
                      ,NetSNMP
                      ,process
diff --git a/changes b/changes
--- a/changes
+++ b/changes
@@ -1,10 +1,23 @@
+0.4.0.0 - 26. March 2024
+  * Add a MonadFail instance of Trouble. Thanks to @arthur-den
+    (https://github.com/arthur-den) for contribution.
+  * P.S. This package could use a new maintainer who is much more connected
+    to the haskell community and ecosystem. Please reach out if you are
+    interested.
+
+0.3.2.6 - ***
+  * Switched to stack as the main building tool. Please raise an issue if
+    you think that its inappropriate for a library.
+  * Automate running tests using CircleCI
+
 0.3.2.5 - 01. December 2016
-  * Taking out the duplcate checking to mkSnmpBulkGet was a total mistake
+  * Taking out the loop checking to mkSnmpBulkGet was a total mistake.
     snmpbulkget reads beyond the needed parts whereas bulkwalk stays within
     the subtree of the requested OID. Thus snmpbulkget is actually returning
-    duplicate results which is ok. They will be filtered in the bulkWalk
-    part
-    Will deprecate the 0.3.2.4 on hackage.
+    duplicate results which is ok. Have reverted the change made in 0.3.2.4
+    and the loops will now be checked in the snmpBulkWalkN after making sure
+    that all the OIDs are from the requested subtree.
+    Deprecates 0.3.2.4
 
 0.3.2.4 - 14. November 2016
   * Throw an error on duplicate OIDs in the mkSnmpBulkGet response
@@ -19,11 +32,11 @@
 
 0.3.2.1 - 11. April 2016
   * Fix parsing IPs. Issue #4 (https://github.com/ptek/netsnmp/issues/4)
-	  In the prevois code, "0.0.0.0" converts to "\NUL.\NUL.\NUL.\NUL"
-	  Thanks to lievenm (https://github.com/lievenm) for pointing it out.
-	* Remove the dependency on utf8-string. Using ByteString.Char8 instead
-	  since the oids we were decoding as utf8 before, are number after all
-	  and should not be in UTF8 range anyway
+    In the prevois code, "0.0.0.0" converts to "\NUL.\NUL.\NUL.\NUL"
+    Thanks to lievenm (https://github.com/lievenm) for pointing it out.
+  * Remove the dependency on utf8-string. Using ByteString.Char8 instead
+    since the oids we were decoding as utf8 before, are number after all
+    and should not be in UTF8 range anyway
 
 0.3.2.0 - 19. June 2015
         * Make the library compile with GHC 7.10.1
diff --git a/src/Network/Protocol/NetSNMP.hsc b/src/Network/Protocol/NetSNMP.hsc
--- a/src/Network/Protocol/NetSNMP.hsc
+++ b/src/Network/Protocol/NetSNMP.hsc
@@ -200,7 +200,7 @@
 -- SNMP_MSG_GETNEXT               Yes   Yes   Yes
 -- SNMP_MSG_RESPONSE              Yes   Yes   Yes
 -- SNMP_MSG_SET                   Yes   Yes   Yes
--- SNMP_MSG_TRAP                  Yes    -     - 
+-- SNMP_MSG_TRAP                  Yes    -     -
 -- SNMP_MSG_GETBULK                -    Yes   Yes
 -- SNMP_MSG_INFORM                 -    Yes   Yes
 -- SNMP_MSG_TRAP2                  -    Yes   Yes
@@ -799,7 +799,7 @@
       -> Ptr CString -> IO ()
 
 snmpError :: Ptr SnmpSession -> IO String
-snmpError p = 
+snmpError p =
   alloca $ \libp ->     -- pointer to library error code
   alloca $ \sysp ->     -- pointer to system error code
   alloca $ \errp -> do  -- pointer to error CString
@@ -814,7 +814,7 @@
 
 -- Return library error description
 -- This one is preferred for all single-session api failures except
--- snmp_sess_open failure.  
+-- snmp_sess_open failure.
 -- library/snmp_api.h
 -- void snmp_sess_error(void *, int *, int *, char **);
 -- foreign import ccall unsafe "net-snmp/net-snmp-includes.h snmp_sess_error"
@@ -863,11 +863,14 @@
               (Right v) -> return (Right (f v))
 
 instance Monad Trouble where
-  return a = Trouble $ return (Right a)
+  return = pure
   m >>= f  = Trouble $ do
     r <- runTrouble m
     case r of (Left s)  -> return (Left s)
               (Right v) -> runTrouble (f v)
+
+instance MonadFail Trouble where
+  fail = Trouble . pure . Left
 
 throwT :: String -> Trouble a
 throwT s = Trouble $ return (Left s)
