diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,5 +1,8 @@
 # Changelog for `proto-lens-arbitrary`
 
+## v0.1.2.6
+- Bump upper bounds to support `proto-lens-0.5.*`.
+
 ## v0.1.2.5
 - Bump the dependency for `QuickCheck-2.12`.
 
diff --git a/proto-lens-arbitrary.cabal b/proto-lens-arbitrary.cabal
--- a/proto-lens-arbitrary.cabal
+++ b/proto-lens-arbitrary.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: 43298dbb52fbba533a149e953e5ee43b13e5d523ff7e8b544e97c05c14ae74db
+-- hash: 5b7052bd8fe8c3d82ae15eddf8ce7bf5a93d78b40004afc0c8a4c94fae4757f1
 
 name:           proto-lens-arbitrary
-version:        0.1.2.5
+version:        0.1.2.6
 synopsis:       Arbitrary instances for proto-lens.
 description:    The proto-lens-arbitrary allows generating arbitrary messages for use with QuickCheck.
 category:       Data
@@ -17,7 +19,6 @@
 license:        BSD3
 license-file:   LICENSE
 build-type:     Simple
-cabal-version:  >= 1.10
 extra-source-files:
     Changelog.md
 
@@ -39,6 +40,6 @@
     , bytestring ==0.10.*
     , containers >=0.5 && <0.7
     , lens-family ==1.2.*
-    , proto-lens ==0.4.*
+    , proto-lens >=0.4 && <0.6
     , text ==1.2.*
   default-language: Haskell2010
diff --git a/src/Data/ProtoLens/Arbitrary.hs b/src/Data/ProtoLens/Arbitrary.hs
--- a/src/Data/ProtoLens/Arbitrary.hs
+++ b/src/Data/ProtoLens/Arbitrary.hs
@@ -107,7 +107,24 @@
 
 shrinkMap :: (Ord key, Message entry) => Lens' entry key -> Lens' entry value
           -> (entry -> [entry]) -> Map key value -> [Map key value]
-shrinkMap keyLens valueLens f = mapEntriesLens keyLens valueLens (shrinkList f)
+shrinkMap keyLens valueLens f = mapEntriesLens keyLens valueLens (shrinkList f')
+  where
+    f' = filter allFieldsAreSet . f
+    -- Strip out all entries whose key or value is not set (and which distinguish
+    -- between being unset and being the default value (proto2, or in proto3 for a
+    -- message value type).
+    -- The representation in the Map (as, effectively, a pair of key and value)
+    -- does not distinguish between unset/default values.  This can lead to
+    -- shrinkMap behaving incorrectly; for example,
+    -- `Map.singleton 0 "abc"` gets represented as
+    -- `[defMessage & #maybe'key .~ Just 0 & #value .~ "abc"]`, which might be
+    -- shrunk to `[defMessage & #maybe'key .~ Nothing & #value .~ "abc"]`,
+    -- which maps back to the same Map representation.
+    -- Work around this for now by just filtering out entries with unset
+    -- optional fields.
+    allFieldsAreSet msg = all (fieldIsSet msg) allFields
+    fieldIsSet msg (FieldDescriptor _ _ (OptionalField l)) = isJust (view l msg)
+    fieldIsSet _ _ = True
 
 shrinkField :: FieldDescriptor msg -> msg -> [msg]
 shrinkField (FieldDescriptor _ ftd fa) = case fa of
@@ -166,6 +183,8 @@
 -- contain duplicate keys that would become de-duped inside the Map. It's only
 -- included here to make it easy to convert from a list of entry Messages to
 -- a Map.
+-- See the comment in shrinkMap for why this is a problem.
+-- TODO: consider a different Message representation for maps.
 mapEntriesLens :: (Ord key, Message entry) =>
         Lens' entry key -> Lens' entry value -> Lens' (Map key value) [entry]
 mapEntriesLens kl vl = lens (mapToEntries kl vl) (const (entriesToMap kl vl))
