diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
 # Changelog
 
+### 0.2.1
+
+* Fix parsing of boundaries if newlines are missing. Thanks to Matthew
+  Bauer.
+* Building this package with ghc versions before 8.x is no longer supported.
+
+### 0.2.0
+
+* Monad.Fail no longer exists in `base-4.13.0.0` and beyond; the function now
+  lives in the class `MonadFail`. We need a major version bump, because this
+  change affects the type signatures of functions we export to our users.
+
 ### 0.1.3
 
 * Improve performance of parsing multipart body. Thanks to Ali Abrar.
diff --git a/Network/Multipart.hs b/Network/Multipart.hs
--- a/Network/Multipart.hs
+++ b/Network/Multipart.hs
@@ -116,15 +116,22 @@
                    --   are not included in any of the strings returned.
                    --   Returns 'Nothing' if there is no boundary.
 splitAtBoundary b s =
-  let bcrlf = BS.append "\r\n--" b
-      (before, t) = breakOn (BS.toStrict bcrlf) s
-  in case BS.stripPrefix bcrlf t of
+  let b' = BS.append "--" b
+      bcrlf = BS.append "\r\n" b'
+
+      -- check if we are at the beginning of a boundary, if so, we
+      -- won’t have a \r\n
+      prefix = if BS.isPrefixOf b' s then b'
+               else bcrlf
+
+      (before, t) = breakOn (BS.toStrict prefix) s
+  in case BS.stripPrefix prefix t of
        Nothing -> Nothing
        Just t' ->
          let after = case BS.stripPrefix "\r\n" t' of
                Nothing -> t'
                Just t'' -> t''
-         in  Just (before, bcrlf, after)
+         in  Just (before, prefix, after)
 
 -- | Check whether a string for which 'isBoundary' returns true
 --   has two dashes after the boudary string.
diff --git a/Network/Multipart/Header.hs b/Network/Multipart/Header.hs
--- a/Network/Multipart/Header.hs
+++ b/Network/Multipart/Header.hs
@@ -44,6 +44,7 @@
                           ) where
 
 import Control.Monad
+import Control.Monad.Fail as MFail
 import Data.Char
 import Data.List
 import qualified Data.Monoid as M
@@ -91,7 +92,7 @@
        _ <- crLf
        return (sp:line)
 
-getHeaderValue :: (Monad m, HeaderValue a) => String -> Headers -> m a
+getHeaderValue :: (MonadFail m, HeaderValue a) => String -> Headers -> m a
 getHeaderValue h hs = lookupM (HeaderName h) hs >>= parseM parseHeaderValue h
 
 --
@@ -183,13 +184,13 @@
 -- | Parse the standard representation of a content-type.
 --   If the input cannot be parsed, this function calls
 --   'fail' with a (hopefully) informative error message.
-parseContentType :: Monad m => String -> m ContentType
+parseContentType :: MonadFail m => String -> m ContentType
 parseContentType = parseM parseHeaderValue "Content-type"
 
 showContentType :: ContentType -> String
 showContentType = prettyHeaderValue
 
-getContentType :: Monad m => Headers -> m ContentType
+getContentType :: MonadFail m => Headers -> m ContentType
 getContentType = getHeaderValue "content-type"
 
 --
@@ -207,7 +208,7 @@
            return $ ContentTransferEncoding (map toLower c_cte)
     prettyHeaderValue (ContentTransferEncoding s) = s
 
-getContentTransferEncoding :: Monad m => Headers -> m ContentTransferEncoding
+getContentTransferEncoding :: MonadFail m => Headers -> m ContentTransferEncoding
 getContentTransferEncoding = getHeaderValue "content-transfer-encoding"
 
 --
@@ -228,21 +229,21 @@
         t ++ concat ["; " ++ n ++ "=" ++ quote v | (n,v) <- hs]
             where quote x = "\"" ++ x ++ "\"" -- NOTE: silly, but de-facto standard
 
-getContentDisposition :: Monad m => Headers -> m ContentDisposition
+getContentDisposition :: MonadFail m => Headers -> m ContentDisposition
 getContentDisposition = getHeaderValue "content-disposition"
 
 --
 -- * Utilities
 --
 
-parseM :: Monad m => Parser a -> SourceName -> String -> m a
+parseM :: MonadFail m => Parser a -> SourceName -> String -> m a
 parseM p n inp =
   case parse p n inp of
-    Left e -> fail (show e)
+    Left e -> MFail.fail (show e)
     Right x -> return x
 
-lookupM :: (Monad m, Eq a, Show a) => a -> [(a,b)] -> m b
-lookupM n = maybe (fail ("No such field: " ++ show n)) return . lookup n
+lookupM :: (MonadFail m, Eq a, Show a) => a -> [(a,b)] -> m b
+lookupM n = maybe (MFail.fail ("No such field: " ++ show n)) return . lookup n
 
 caseInsensitiveEq :: String -> String -> Bool
 caseInsensitiveEq x y = map toLower x == map toLower y
diff --git a/multipart.cabal b/multipart.cabal
--- a/multipart.cabal
+++ b/multipart.cabal
@@ -1,7 +1,7 @@
 name:                multipart
-version:             0.1.3
-synopsis:            HTTP multipart split out of the cgi package
-description:         HTTP multipart split out of the cgi package
+version:             0.2.1
+synopsis:            Parsers for the HTTP multipart format
+description:         Parsers and data types for the HTTP multipart format from RFC2046.
 copyright:           Bjorn Bringert, Andy Gill, Anders Kaseorg, Ian Lynagh, Erik Meijer, Sven Panne, Jeremy Shaw
 category:            Network
 maintainer:          code@silk.co
@@ -11,6 +11,7 @@
 license-file:        LICENSE
 build-type:          Simple
 cabal-version:       >=1.10
+tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.1
 
 extra-source-files:
   CHANGELOG.md
