diff --git a/core/network/src/protocol/sync/extra_requests.rs b/core/network/src/protocol/sync/extra_requests.rs
index 6f9103d38d6e3e82570f9f103e21831e1a763597..28ed5fed9f6829a7894f7cc18b7c578a6977ff2c 100644
--- a/core/network/src/protocol/sync/extra_requests.rs
+++ b/core/network/src/protocol/sync/extra_requests.rs
@@ -138,7 +138,10 @@ impl<B: BlockT> ExtraRequests<B> {
 		}
 
 		if best_finalized_number > self.best_seen_finalized_number {
-			match self.tree.finalize(
+			// normally we'll receive finality notifications for every block => finalize would be enough
+			// but if many blocks are finalized at once, some notifications may be omitted
+			// => let's use finalize_with_ancestors here
+			match self.tree.finalize_with_ancestors(
 				best_finalized_hash,
 				best_finalized_number,
 				&is_descendent_of,
@@ -437,6 +440,26 @@ mod tests {
 		assert_eq!(finality_proofs.pending_requests.iter().collect::<Vec<_>>(), Vec::<&(Hash, u64)>::new());
 	}
 
+	#[test]
+	fn anecstor_roots_are_finalized_when_finality_notification_is_missed() {
+		let mut finality_proofs = ExtraRequests::<Block>::new();
+
+		let hash4 = [4; 32].into();
+		let hash5 = [5; 32].into();
+
+		fn is_descendent_of(base: &Hash, target: &Hash) -> Result<bool, ClientError> {
+			Ok(target[0] >= base[0])
+		}
+
+		// schedule request for #4
+		finality_proofs.schedule((hash4, 4), is_descendent_of);
+
+		// receive finality notification for #5 (missing notification for #4!!!)
+		finality_proofs.importing_requests.insert((hash4, 5));
+		finality_proofs.on_block_finalized(&hash5, 5, is_descendent_of).unwrap();
+		assert_eq!(finality_proofs.tree.roots().count(), 0);
+	}
+
 	// Some Arbitrary instances to allow easy construction of random peer sets:
 
 	#[derive(Debug, Clone)]