diff --git a/block/qcow2-dedup.c b/block/qcow2-dedup.c
index 80e9477..097d71b 100644
--- a/block/qcow2-dedup.c
+++ b/block/qcow2-dedup.c
@@ -743,8 +743,9 @@ void coroutine_fn qcow2_co_load_dedup_hashes(void *opaque)
             error_report("Failed to load deduplication hash.");
         }
 
-        /* if the hash is not null load it into the tree */
-        if (memcmp(hash, null_hash, HASH_LENGTH)) {
+        /* if the hash is not null load it into red black tree */
+        if (memcmp(hash, null_hash, HASH_LENGTH) &&
+            !(first_logical_offset & QCOW_FLAG_MAX_REFCOUNT)) {
             hash_node = qcow2_dedup_build_qcow_hash_node(hash,
                                                          i * s->cluster_sectors,
                                                          first_logical_offset);
@@ -809,3 +810,44 @@ void qcow2_dedup_close(BlockDriverState *bs)
     BDRVQcowState *s = bs->opaque;
     g_free(s->dedup_table);
 }
+
+static void qcow2_dedup_refcount_limit_reached(BlockDriverState *bs,
+                                        uint64_t cluster_index,
+                                        bool bottom)
+{
+    BDRVQcowState *s = bs->opaque;
+    QCowHashNode *hash_node;
+    uint64_t offset = cluster_index * s->cluster_sectors;
+
+    hash_node =  g_tree_lookup(s->dedup_tree_by_offset, &offset);
+    if (!hash_node) {
+        return;
+    }
+
+    if (bottom) {
+        /* clear the hash from disk */
+        memset(hash_node->hash, 0, HASH_LENGTH);
+    } else {
+        /* mark this hash so we won't load it anymore at startup */
+        hash_node->first_logical_offset |= QCOW_FLAG_MAX_REFCOUNT;
+    }
+    qcow2_dedup_read_write_hash(bs,
+                                &hash_node->hash,
+                                &hash_node->first_logical_offset,
+                                hash_node->offset,
+                                true);
+    g_tree_remove(s->dedup_tree_by_offset, &hash_node->offset);
+    g_tree_remove(s->dedup_tree_by_hash, hash_node->hash);
+}
+
+void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
+                                      uint64_t cluster_index)
+{
+    qcow2_dedup_refcount_limit_reached(bs, cluster_index, true);
+}
+
+void qcow2_dedup_refcount_max_reached(BlockDriverState *bs,
+                                      uint64_t cluster_index)
+{
+    qcow2_dedup_refcount_limit_reached(bs, cluster_index, false);
+}
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 7681001..efc1179 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -492,6 +492,12 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
             ret = -EINVAL;
             goto fail;
         }
+        if (s->has_dedup && refcount == 0) {
+            qcow2_dedup_refcount_zero_reached(bs, cluster_index);
+        }
+        if (s->has_dedup && refcount == 0xffff) {
+            qcow2_dedup_refcount_max_reached(bs, cluster_index);
+        }
         if (refcount == 0 && cluster_index < s->free_cluster_index) {
             s->free_cluster_index = cluster_index;
         }
diff --git a/block/qcow2.h b/block/qcow2.h
index 90dcdd9..8852696 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -60,6 +60,8 @@
 
 #define DEFAULT_CLUSTER_SIZE 65536
 
+/* indicate that this cluster refcount has reached its maximum value */
+#define QCOW_FLAG_MAX_REFCOUNT (1LL << 61)
 /* indicate that the hash structure is empty and miss offset */
 #define QCOW_FLAG_EMPTY   (1LL << 62)
 /* indicate that the cluster for this hash has QCOW_OFLAG_COPIED on disk */
@@ -409,5 +411,9 @@ int qcow2_dedup_grow_table(BlockDriverState *bs,
                            bool exact_size);
 int qcow2_dedup_init(BlockDriverState *bs);
 void qcow2_dedup_close(BlockDriverState *bs);
+void qcow2_dedup_refcount_zero_reached(BlockDriverState *bs,
+                                       uint64_t cluster_index);
+void qcow2_dedup_refcount_max_reached(BlockDriverState *bs,
+                                      uint64_t cluster_index);
 
 #endif
