diff --git a/genvalidity-bytestring.cabal b/genvalidity-bytestring.cabal
--- a/genvalidity-bytestring.cabal
+++ b/genvalidity-bytestring.cabal
@@ -1,11 +1,13 @@
--- This file has been generated from package.yaml by hpack version 0.28.2.
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.31.1.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 8d24c1a1afb58b8b160171f40cb1613fb2516e04ac4328adae840fbb3ae15d2d
+-- hash: a576909f691b01e569d7164556dc20d0f9e6ca5cac0b6db9bab76489fe3ef281
 
 name:           genvalidity-bytestring
-version:        0.3.0.1
+version:        0.4.0.0
 synopsis:       GenValidity support for ByteString
 description:    Please see README.md
 category:       Testing
@@ -18,7 +20,6 @@
 license:        MIT
 license-file:   LICENSE
 build-type:     Simple
-cabal-version:  >= 1.10
 
 source-repository head
   type: git
diff --git a/src/Data/GenValidity/ByteString.hs b/src/Data/GenValidity/ByteString.hs
--- a/src/Data/GenValidity/ByteString.hs
+++ b/src/Data/GenValidity/ByteString.hs
@@ -15,25 +15,54 @@
 import qualified Data.ByteString.Lazy as LB
 import qualified Data.ByteString.Lazy.Internal as LB
 
--- | WARNING: Unchecked ByteStrings are *seriously* broken.
--- The pointer may still point to something which is fine, but
--- the offset and length will most likely be complete nonsense.
--- This will most-likely lead to segfaults.
 instance GenUnchecked SB.ByteString where
-    genUnchecked = do
-        ws <- genUnchecked
-        -- TODO what do we do about the foreign pointer?
-        let SB.PS p _ _ = SB.pack ws
-        SB.PS p <$> genUnchecked <*> genUnchecked
-    shrinkUnchecked (SB.PS p o l) =
-        [SB.PS p o' l' | (o', l') <- shrinkUnchecked (o, l)]
+    genUnchecked =
+        error $
+        unlines
+            [ "Data.GenValidity.ByteString.genUnchecked :: Strict.ByteString"
+            , "You probably do not want to use this."
+            , "You probably want to use 'genValid' instead."
+            , "See https://github.com/NorfairKing/validity/blob/master/docs/BYTESTRING.md"
+            ]
+    shrinkUnchecked =
+        error $
+        unlines
+            [ "Data.GenValidity.ByteString.shrinkUnchecked :: Strict.ByteString -> [Strict.ByteString]"
+            , "You probably do not want to use this."
+            , "You probably want to use 'shrinkValid' instead."
+            , "See https://github.com/NorfairKing/validity/blob/master/docs/BYTESTRING.md"
+            ]
 
+-- |
+--
+-- > genValid = SB.pack <$> genValid
+-- > shrinkValid = fmap SB.pack . shrinkValid . SB.unpack
 instance GenValid SB.ByteString where
     genValid = SB.pack <$> genValid
     shrinkValid = fmap SB.pack . shrinkValid . SB.unpack
 
-instance GenInvalid SB.ByteString
+-- | WARNING: Unchecked ByteStrings are __seriously__ broken.
+--
+-- The pointer may still point to something which is fine, but
+-- the offset and length will most likely be complete nonsense.
+-- This will most-likely lead to segfaults.
+--
+-- This means that 'genUnchecked' will generate seriously broken 'ByteString' values.
+-- This is __intended__. If you need valid 'ByteString' values, use 'GenValid' instead.
+--
+-- Make sure to not use any test suite combinators or property combinators that involve
+-- 'GenInvalid' (like 'genValiditySpec') on types that contain 'ByteString' values.
+genTrulyUncheckedStrictByteString :: Gen SB.ByteString
+genTrulyUncheckedStrictByteString = do
+    ws <- genUnchecked
+    -- TODO what do we do about the foreign pointer?
+    let SB.PS p _ _ = SB.pack ws
+    SB.PS p <$> genUnchecked <*> genUnchecked
 
+shrinkTrulyUncheckedStrictByteString :: SB.ByteString -> [SB.ByteString]
+shrinkTrulyUncheckedStrictByteString (SB.PS p o l) =
+    [SB.PS p o' l' | (o', l') <- shrinkUnchecked (o, l)]
+
 instance GenUnchecked LB.ByteString where
     genUnchecked =
         sized $ \n ->
@@ -44,12 +73,13 @@
                     sb <- resize a genUnchecked
                     lb <- resize b genUnchecked
                     pure $ LB.Chunk sb lb
-    shrinkUnchecked LB.Empty = []
-    shrinkUnchecked (LB.Chunk sb lb) =
-        LB.Empty : [LB.Chunk sb' lb' | (sb', lb') <- shrinkUnchecked (sb, lb)]
+    shrinkUnchecked lb_ =
+        case lb_ of
+            LB.Empty -> []
+            (LB.Chunk sb lb) ->
+                LB.Empty :
+                [LB.Chunk sb' lb' | (sb', lb') <- shrinkUnchecked (sb, lb)]
 
 instance GenValid LB.ByteString where
     genValid = LB.pack <$> genValid
     shrinkValid = fmap LB.pack . shrinkValid . LB.unpack
-
-instance GenInvalid LB.ByteString
diff --git a/test/Data/GenValidity/ByteStringSpec.hs b/test/Data/GenValidity/ByteStringSpec.hs
--- a/test/Data/GenValidity/ByteStringSpec.hs
+++ b/test/Data/GenValidity/ByteStringSpec.hs
@@ -28,29 +28,13 @@
 
 spec :: Spec
 spec = do
-    describe "genUnchecked :: Gen SB.ByteString" $ do
-        checkable (genUnchecked :: Gen SB.ByteString)
-        -- showable (genUnchecked :: Gen SB.ByteString) DOES NOT HOLD
-    describe "genValid :: Gen SB.ByteString" $ do
-        checkable (genValid :: Gen SB.ByteString)
-        showable (genValid :: Gen SB.ByteString)
-        it "generates valid strict bytestring" $
-            forAll (genValid :: Gen SB.ByteString) isValid
-    describe "genInvalid :: Gen SB.ByteString" $ do
-        checkable (genInvalid :: Gen SB.ByteString)
-        -- showable (genInvalid :: Gen SB.ByteString) DOES NOT HOLD
-        it "generates invalid strict bytestring" $
-            forAll (genInvalid :: Gen SB.ByteString) isInvalid
-    describe "genUnchecked :: Gen LB.ByteString" $ do
-        checkable (genUnchecked :: Gen LB.ByteString)
-        -- showable (genUnchecked :: Gen LB.ByteString) DOES NOT HOLD
-    describe "genValid :: Gen LB.ByteString" $ do
-        checkable (genValid :: Gen LB.ByteString)
-        showable (genValid :: Gen LB.ByteString)
-        it "generates valid lazy bytestring" $
-            forAll (genValid :: Gen LB.ByteString) isValid
-    describe "genInvalid :: Gen LB.ByteString" $ do
-        checkable (genInvalid :: Gen LB.ByteString)
-        -- showable (genInvalid :: Gen LB.ByteString) DOES NOT HOLD
-        it "generates invalid lazy bytestring" $
-            forAll (genInvalid :: Gen LB.ByteString) isInvalid
+    do describe "genValid :: Gen SB.ByteString" $ do
+           checkable (genValid :: Gen SB.ByteString)
+           showable (genValid :: Gen SB.ByteString)
+           it "generates valid strict bytestring" $
+               forAll (genValid :: Gen SB.ByteString) isValid
+       describe "genValid :: Gen LB.ByteString" $ do
+           checkable (genValid :: Gen LB.ByteString)
+           showable (genValid :: Gen LB.ByteString)
+           it "generates valid lazy bytestring" $
+               forAll (genValid :: Gen LB.ByteString) isValid
