diff --git a/ocfl/data/validation-errors.json b/ocfl/data/validation-errors.json
index 56eed29..64f9dbf 100644
--- a/ocfl/data/validation-errors.json
+++ b/ocfl/data/validation-errors.json
@@ -513,7 +513,13 @@
        "en": "OCFL Object %s inventory manifest content path %s must not begin or end with /."
     }
   },
-  "E101": {
+  "E101a": {
+    "params": ["where", "path"],
+    "description": {
+       "en": "OCFL Object %s inventory manifest content path %s is repeated."
+    }
+  },
+  "E101b": {
     "params": ["where", "path"],
     "description": {
        "en": "OCFL Object %s inventory manifest content path %s used as both a directory and a file path."
diff --git a/ocfl/inventory_validator.py b/ocfl/inventory_validator.py
index 4a918b5..83a0f6e 100644
--- a/ocfl/inventory_validator.py
+++ b/ocfl/inventory_validator.py
@@ -157,7 +157,7 @@ class InventoryValidator():
             # Check for conflicting content paths
             for path in content_directories:
                 if path in content_paths:
-                    self.error("E101", path=path)
+                    self.error("E101b", path=path)
         return manifest_files, manifest_files_correct_format, unnormalized_digests
 
     def validate_fixity(self, fixity, manifest_files):
@@ -417,7 +417,10 @@ class InventoryValidator():
             if element in ('', '.', '..'):
                 self.error("E099", path=path)
                 return False
-        # Accumulate paths and directories
+        # Accumulate paths and directories if not seen before
+        if path in content_paths:
+            self.error("E101a", path=path)
+            return False
         content_paths.add(path)
         content_directories.add('/'.join([m.group(1)] + elements[0:-1]))
         return True

diff --git a/tests/test_inventory_validator.py b/tests/test_inventory_validator.py
index 5db1512..af61b9d 100644
--- a/tests/test_inventory_validator.py
+++ b/tests/test_inventory_validator.py
@@ -101,7 +101,7 @@ class TestAll(unittest.TestCase):
         log.clear()
         # Conflicting content paths
         iv.validate_manifest({"067eca3f5b024afa00aeac03a3c42dc0042bf43cba56104037abea8b365c0cf672f0e0c14c91b82bbce6b1464e231ac285d630a82cd4d4a7b194bea04d4b2eb7": ['v1/content/a', 'v1/content/a/b']})
-        self.assertEqual(log.errors, ['E101'])
+        self.assertEqual(log.errors, ['E101b'])
 
     def test_validate_fixity(self):
         """Test validate_fixity method."""
@@ -373,6 +373,9 @@ class TestAll(unittest.TestCase):
         log.clear()
         self.assertFalse(iv.check_content_path('v1/xyz/.', cp, cd))
         self.assertEqual(log.errors, ['E099'])
+        log.clear()
+        self.assertFalse(iv.check_content_path('v1/xyz/anything', cp, cd))
+        self.assertEqual(log.errors, ['E101a'])
         # Good cases
         log.clear()
         self.assertTrue(iv.check_content_path('v1/xyz/.secret/d', cp, cd))

Correctly handle validation with multiple entries for a given digest in `manifest`
See error case https://github.com/OCFL/fixtures/pull/78
tests/test_inventory_validator.py::TestAll::test_check_content_path tests/test_inventory_validator.py::TestAll::test_validate_manifest
tests/test_inventory_validator.py::TestAll::test_bad_inventory_files tests/test_inventory_validator.py::TestAll::test_check_digests_present_and_used tests/test_inventory_validator.py::TestAll::test_check_logical_path tests/test_inventory_validator.py::TestAll::test_digest_regex tests/test_inventory_validator.py::TestAll::test_init tests/test_inventory_validator.py::TestAll::test_validate tests/test_inventory_validator.py::TestAll::test_validate_as_prior_version tests/test_inventory_validator.py::TestAll::test_validate_fixity tests/test_inventory_validator.py::TestAll::test_validate_state_block tests/test_inventory_validator.py::TestAll::test_validate_version_sequence tests/test_inventory_validator.py::TestAll::test_validate_versions