diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,6 @@
 # ChangeLog
 
-## 0.4.0
+## 0.4.1
 
 * Breaking change in the encoding of Map / Set / IntMap / IntSet,
   to use ascending key order. Attempting to decode data written by
@@ -15,6 +15,16 @@
 
 * Performance improvement of the 'Peek' monad, by introducing more
   strictness.  This required a change to the internal API.
+
+* API and behavior of 'Data.Store.Version' changed. Previously, it
+  would check the version tag after decoding the contents. It now
+  also stores a magic Word32 tag at the beginning, so that it fails
+  more gracefully when decoding input that lacks encoded version
+  info.
+
+## 0.4.0
+
+Deprecated in favor of 0.4.1
 
 ## 0.3.1
 
diff --git a/src/Data/Store/Internal.hs b/src/Data/Store/Internal.hs
--- a/src/Data/Store/Internal.hs
+++ b/src/Data/Store/Internal.hs
@@ -56,6 +56,7 @@
     , GStorePeek, genericPeek
     -- ** Peek utilities
     , skip, isolate
+    , peekMagic
     -- ** Static Size type
     --
     -- This portion of the library is still work-in-progress.
@@ -250,11 +251,11 @@
 -- Throws a 'PeekException' if the value isn't present.
 peekMagic
     :: (Eq a, Show a, Store a)
-    => a -> Peek ()
-peekMagic x = do
+    => String -> a -> Peek ()
+peekMagic markedThing x = do
     x' <- peek
     when (x' /= x) $
-        fail ("Expected marker: " ++ show x ++ " but got: " ++ show x')
+        fail ("Expected marker for " ++ markedThing ++ ": " ++ show x ++ " but got: " ++ show x')
 {-# INLINE peekMagic #-}
 
 -- | Like 'sizeMap' but should only be used for ordered containers where
@@ -284,7 +285,7 @@
        -- 'Map.fromDistinctAscList'.
     -> Peek t
 peekOrdMapWith f = do
-    peekMagic markMapPokedInAscendingOrder
+    peekMagic "ascending Map / IntMap" markMapPokedInAscendingOrder
     f <$> peek
 {-# INLINE peekOrdMapWith #-}
 
@@ -824,4 +825,3 @@
 $(reifyManyWithoutInstances ''Store [''Info] (const True) >>=
 --   mapM (\name -> deriveStore [] (ConT name) .dtCons =<< reifyDataType name))
    mapM (\name -> return (deriveGenericInstance [] (ConT name))))
-
diff --git a/src/Data/Store/Version.hs b/src/Data/Store/Version.hs
--- a/src/Data/Store/Version.hs
+++ b/src/Data/Store/Version.hs
@@ -23,16 +23,13 @@
 -- will be minimized when directly feasible.
 module Data.Store.Version
     ( StoreVersion(..)
-    , WithVersion(..)
     , VersionConfig(..)
     , hashedVersionConfig
     , namedVersionConfig
-    , wrapVersion
-    , checkVersion
-    , VersionCheckException(..)
+    , encodeWithVersionQ
+    , decodeWithVersionQ
     ) where
 
-import           Control.Exception
 import           Control.Monad
 import           Control.Monad.Trans.State
 import qualified Crypto.Hash.SHA1 as SHA1
@@ -48,6 +45,7 @@
 import           Data.Text.Encoding.Error (lenientDecode)
 import qualified Data.Text.IO as T
 import           Data.Typeable.Internal (TypeRep(..))
+import           Data.Word (Word32)
 import           GHC.Generics (Generic)
 import           Language.Haskell.TH
 import           System.Directory
@@ -59,11 +57,6 @@
 newtype StoreVersion = StoreVersion { unStoreVersion :: BS.ByteString }
     deriving (Eq, Show, Ord, Data, Typeable, Generic, Store)
 
-data WithVersion a = WithVersion a StoreVersion
-    deriving (Eq, Show, Ord, Data, Typeable, Generic)
-
-instance Store a => Store (WithVersion a)
-
 -- | Configuration for the version checking of a particular type.
 data VersionConfig a = VersionConfig
     { vcExpectedHash :: Maybe String
@@ -92,13 +85,13 @@
     , vcRenames = M.empty
     }
 
-wrapVersion :: Data a => VersionConfig a -> Q Exp
-wrapVersion = impl Wrap
+encodeWithVersionQ :: Data a => VersionConfig a -> Q Exp
+encodeWithVersionQ = impl Encode
 
-checkVersion :: Data a => VersionConfig a -> Q Exp
-checkVersion = impl Check
+decodeWithVersionQ :: Data a => VersionConfig a -> Q Exp
+decodeWithVersionQ = impl Decode
 
-data WhichFunc = Wrap | Check
+data WhichFunc = Encode | Decode
 
 impl :: forall a. Data a => WhichFunc -> VersionConfig a -> Q Exp
 impl wf vc = do
@@ -131,15 +124,16 @@
                         ", but " ++ show expectedHash ++ " is specified.\n" ++
                         "The data used to construct the hash has been written to " ++ show newPath ++
                         extraMsg ++ "\n"
+    let atype = typeRepToType (typeRep proxy)
     case wf of
-        Wrap -> [e| (\x -> (x :: $(typeRepToType (typeRep proxy))) `WithVersion` $(version)) |]
-        Check -> [e| (\(WithVersion x gotVersion) ->
-                        if gotVersion /= $(version)
-                            then Left (VersionCheckException
-                                { expectedVersion = $(version)
-                                , receivedVersion = gotVersion
-                                })
-                            else Right x) |]
+        Encode -> [e| \x -> ( getSize markEncodedVersion + getSize $(version) + getSize x
+                            , poke markEncodedVersion >> poke $(version) >> poke (x :: $(atype))) |]
+        Decode -> [e| do
+            peekMagic "version tag" markEncodedVersion
+            gotVersion <- peek
+            if gotVersion /= $(version)
+                then fail (displayVersionError $(version) gotVersion)
+                else peek :: Peek $(atype) |]
 
 {-
                             txtWithComments <- runIO $ T.readFile path
@@ -286,26 +280,11 @@
 tyConOf :: Typeable a => Proxy a -> TyCon
 tyConOf = typeRepTyCon . typeRep
 
-data VersionCheckException = VersionCheckException
-    { expectedVersion :: StoreVersion
-    , receivedVersion :: StoreVersion
-    } deriving
-#if MIN_VERSION_base(4,8,0)
-        (Typeable, Show)
-
-instance Exception VersionCheckException where
-    displayException = displayVCE
-#else
-        (Typeable)
-
-instance Show VersionCheckException where
-    show = displayVCE
-
-instance Exception VersionCheckException
-#endif
-
-displayVCE :: VersionCheckException -> String
-displayVCE VersionCheckException{..} =
+displayVersionError :: StoreVersion -> StoreVersion -> String
+displayVersionError expectedVersion receivedVersion =
     "Mismatch detected by Data.Store.Version - expected " ++
     T.unpack (decodeUtf8With lenientDecode (unStoreVersion expectedVersion)) ++ " but got " ++
     T.unpack (decodeUtf8With lenientDecode (unStoreVersion receivedVersion))
+
+markEncodedVersion :: Word32
+markEncodedVersion = 3908297288
diff --git a/store.cabal b/store.cabal
--- a/store.cabal
+++ b/store.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           store
-version:        0.4.0
+version:        0.4.1
 synopsis:       Fast binary serialization
 category:       Serialization, Data
 homepage:       https://github.com/fpco/store#readme
