diff --git a/hw-ip.cabal b/hw-ip.cabal
--- a/hw-ip.cabal
+++ b/hw-ip.cabal
@@ -3,13 +3,15 @@
 -- see: https://github.com/sol/hpack
 
 name:           hw-ip
-version:        0.4.0
+version:        0.4.1
 synopsis:       Library for manipulating IP addresses and CIDR blocks
 description:    Please see README.md
 category:       Network
 homepage:       https://github.com/haskell-works/hw-ip#readme
 bug-reports:    https://github.com/haskell-works/hw-ip/issues
-author:         John
+author:         John Ky,
+                David Turnbull,
+                Jian Wan
 maintainer:     newhoggy@gmail.com
 copyright:      2018 John Ky
 license:        BSD3
diff --git a/src/HaskellWorks/Data/Network/Ip/Type.hs b/src/HaskellWorks/Data/Network/Ip/Type.hs
--- a/src/HaskellWorks/Data/Network/Ip/Type.hs
+++ b/src/HaskellWorks/Data/Network/Ip/Type.hs
@@ -10,11 +10,14 @@
   , Ipv4Block(..)
   ) where
 
+import Data.Maybe
 import Data.Word
 import GHC.Generics
 import HaskellWorks.Data.Bits.BitWise
+import Control.Monad
 
 import qualified Data.Attoparsec.Text                  as AP
+import qualified Data.Bits                             as B
 import qualified Data.Text                             as T
 import qualified HaskellWorks.Data.Network.Ip.Internal as I
 import qualified Text.ParserCombinators.ReadPrec       as RP
@@ -55,7 +58,18 @@
   readsPrec :: Int -> String -> [(Ipv4Block, String)]
   readsPrec _ s = case AP.parseWith (return mempty) (I.whitespace *> I.ipv4Block) (T.pack s) of
     Just result -> case result of
-      AP.Done i (a, m) -> [(Ipv4Block (Ipv4Address a) (Ipv4NetMask m), T.unpack i)]
+      AP.Done i (a, m) ->
+        case validIpv4Block $ Ipv4Block (Ipv4Address a) (Ipv4NetMask m) of
+          Just b  -> [(b, T.unpack i)]
+          Nothing -> []
       AP.Partial _     -> []
       AP.Fail a b c    -> []
     Nothing -> []
+
+-- shift the address left by the amount of mask bits to reveal only host bits
+-- if any bits left are non-zero, then the mask is not big enough
+validIpv4Block :: Ipv4Block -> Maybe Ipv4Block
+validIpv4Block b@(Ipv4Block (Ipv4Address word) (Ipv4NetMask mask)) =
+  if word `B.shiftL` fromIntegral mask `B.xor` 0 == 0
+    then pure b
+    else Nothing
diff --git a/test/HaskellWorks/Data/Network/IpSpec.hs b/test/HaskellWorks/Data/Network/IpSpec.hs
--- a/test/HaskellWorks/Data/Network/IpSpec.hs
+++ b/test/HaskellWorks/Data/Network/IpSpec.hs
@@ -9,6 +9,7 @@
 import Test.Hspec
 
 import qualified Data.Attoparsec.Text as AP
+import qualified Text.Read as TR
 import qualified Data.Text as T
 import qualified Hedgehog.Gen as G
 import qualified Hedgehog.Range as R
@@ -57,8 +58,8 @@
       show (lastIpv4Address  $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 21)) === "255.0.7.255"
 
     it "should implement read" $ require $ property $ do
-      read "1.2.3.4/8"  === Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 8)
-      read "1.2.3.4/0"  === Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 0)
+      read "1.0.0.0/8"  === Ipv4Block (Ipv4Address 0x01000000) (Ipv4NetMask 8)
+      read "1.2.0.0/16" === Ipv4Block (Ipv4Address 0x01020000) (Ipv4NetMask 16)
       read "1.2.3.4/32" === Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 32)
 
     it "should implement splitBlock" $ require $ property $ do
@@ -70,3 +71,8 @@
     it "should implement blockSize" $ require $ property $ do
       blockSize (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 32)) === 1
       blockSize (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask  0)) === 0x100000000
+
+    it "should validate masks" $ require $ property $ do
+      (TR.readMaybe "1.2.3.4/8"  :: Maybe Ipv4Block) === Nothing
+      (TR.readMaybe "1.2.3.4/0"  :: Maybe Ipv4Block) === Nothing
+      (TR.readMaybe "1.2.3.4/32" :: Maybe Ipv4Block) === (Just $ Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 32))
