diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01f9b575..ba9ff153 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
 
 * Adds support of mutable CellViewModels.
 * Changes `TableViewSectionedDataSource` default parameters `canEditRowAtIndexPath` and `canMoveRowAtIndexPath` to align with iOS default behavior #383
+* Fixes failing duplicate identity detection
 
 ## [4.0.1](https://github.com/RxSwiftCommunity/RxDataSources/releases/tag/4.0.1)
 
diff --git a/Sources/Differentiator/Diff.swift b/Sources/Differentiator/Diff.swift
index 7e4b8712..a393adb0 100644
--- a/Sources/Differentiator/Diff.swift
+++ b/Sources/Differentiator/Diff.swift
@@ -199,11 +199,19 @@ public enum Diff {
                     dictionary[key] = i
                 }
 
+                var finalKeys = Set<OptimizedIdentity<Identity>>()
+
                 for (i, items) in finalItemCache.enumerated() {
                     for j in 0 ..< items.count {
                         let item = items[j]
                         var identity = item.identity
                         let key = OptimizedIdentity(&identity)
+
+                        if finalKeys.contains(key) {
+                            throw Error.duplicateItem(item: item)
+                        }
+                        finalKeys.insert(key)
+
                         guard let initialItemPathIndex = dictionary[key] else {
                             continue
                         }
@@ -518,8 +526,16 @@ public enum Diff {
                 var initialSectionData = ContiguousArray<SectionAssociatedData>(repeating: SectionAssociatedData.initial, count: initialSections.count)
                 var finalSectionData = ContiguousArray<SectionAssociatedData>(repeating: SectionAssociatedData.initial, count: finalSections.count)
 
+                var finalSectionIdentities = Set<Section.Identity>()
+
                 for (i, section) in finalSections.enumerated() {
                     finalSectionData[i].itemCount = finalSections[i].items.count
+
+                    if finalSectionIdentities.contains(section.identity) {
+                        throw Error.duplicateSection(section: section)
+                    }
+                    finalSectionIdentities.insert(section.identity)
+
                     guard let initialSectionIndex = initialSectionIndexes[section.identity] else {
                         continue
                     }
diff --git a/Tests/RxDataSourcesTests/AlgorithmTests.swift b/Tests/RxDataSourcesTests/AlgorithmTests.swift
index e90a464c..844b537f 100644
--- a/Tests/RxDataSourcesTests/AlgorithmTests.swift
+++ b/Tests/RxDataSourcesTests/AlgorithmTests.swift
@@ -320,8 +320,77 @@ extension AlgorithmTests {
 
 // errors
 extension AlgorithmTests {
-    func testThrowsErrorOnDuplicateItem() {
-        let initial: [s] = [
+    func testThrowsErrorOnDuplicateItem_inInitialSections() {
+        let sections: [s] = [
+            s(1, [
+                i(1111, ""),
+                i(1111, "")
+            ])
+        ]
+
+        do {
+            _ = try Diff.differencesForSectionedView(initialSections: sections, finalSections: sections)
+            XCTFail("Should throw exception")
+        }
+        catch let exception {
+            guard case let .duplicateItem(item) = exception as! Diff.Error else {
+                XCTFail("Not required error")
+                return
+            }
+
+            XCTAssertEqual(item as! i, i(1111, ""))
+        }
+    }
+
+    func testThrowsErrorOnDuplicateItem_inFinalSections() {
+        let final: [s] = [
+            s(1, [
+                i(1111, ""),
+                i(1111, "")
+            ])
+        ]
+
+        do {
+            _ = try Diff.differencesForSectionedView(initialSections: [], finalSections: final)
+            XCTFail("Should throw exception")
+        }
+        catch let exception {
+            guard case let .duplicateItem(item) = exception as! Diff.Error else {
+                XCTFail("Not required error")
+                return
+            }
+
+            XCTAssertEqual(item as! i, i(1111, ""))
+        }
+    }
+
+    func testThrowsErrorOnDuplicateItemInDifferentSection_inInitialSections() {
+        let sections: [s] = [
+            s(1, [
+                i(1111, "")
+            ]),
+            s(2, [
+                i(1111, "")
+            ])
+
+        ]
+
+        do {
+            _ = try Diff.differencesForSectionedView(initialSections: sections, finalSections: sections)
+            XCTFail("Should throw exception")
+        }
+        catch let exception {
+            guard case let .duplicateItem(item) = exception as! Diff.Error else {
+                XCTFail("Not required error")
+                return
+            }
+
+            XCTAssertEqual(item as! i, i(1111, ""))
+        }
+    }
+
+    func testThrowsErrorOnDuplicateItemInDifferentSection_inFinalSections() {
+        let final: [s] = [
             s(1, [
                 i(1111, "")
                 ]),
@@ -332,7 +401,7 @@ extension AlgorithmTests {
             ]
 
         do {
-            _ = try Diff.differencesForSectionedView(initialSections: initial, finalSections: initial)
+            _ = try Diff.differencesForSectionedView(initialSections: [], finalSections: final)
             XCTFail("Should throw exception")
         }
         catch let exception {
@@ -345,8 +414,33 @@ extension AlgorithmTests {
         }
     }
 
-    func testThrowsErrorOnDuplicateSection() {
-        let initial: [s] = [
+    func testThrowsErrorOnDuplicateSection_inInitialSections() {
+        let sections: [s] = [
+            s(1, [
+                i(1111, "")
+            ]),
+            s(1, [
+                i(1112, "")
+            ])
+        ]
+
+        do {
+            _ = try Diff.differencesForSectionedView(initialSections: sections, finalSections: sections)
+            XCTFail("Should throw exception")
+        }
+        catch let exception {
+            guard case let .duplicateSection(section) = exception as! Diff.Error else {
+                XCTFail("Not required error")
+                return
+            }
+
+            XCTAssertEqual(section as! s, s(1, [
+                i(1112, "")
+            ]))
+        }
+    }
+    func testThrowsErrorOnDuplicateSection_inFinalSections() {
+        let final: [s] = [
             s(1, [
                 i(1111, "")
                 ]),
@@ -357,7 +451,7 @@ extension AlgorithmTests {
             ]
 
         do {
-            _ = try Diff.differencesForSectionedView(initialSections: initial, finalSections: initial)
+            _ = try Diff.differencesForSectionedView(initialSections: [], finalSections: final)
             XCTFail("Should throw exception")
         }
         catch let exception {