diff --git a/src/libknot/dnssec/zone-nsec.c b/src/libknot/dnssec/zone-nsec.c
index 577f6f638fa60c2c0b26b92ccd96231a3476e968..e33975c810f26d03e07b22ab7d8c7b1af8f00b22 100644
--- a/src/libknot/dnssec/zone-nsec.c
+++ b/src/libknot/dnssec/zone-nsec.c
@@ -786,6 +786,88 @@ static int create_nsec3_chain(const knot_zone_contents_t *zone, uint32_t ttl,
 	return result;
 }
 
+/* - deleting NSEC3 chain -------------------------------------------------- */
+
+typedef struct {
+	knot_changeset_t *changeset;
+	int result;
+} nsec3_chain_delete_data_t;
+
+static int copy_node_and_delete(const knot_rrset_t *rrset,
+                                knot_changeset_t *changeset)
+{
+	knot_rrset_t *copy = NULL;
+	int result = knot_rrset_deep_copy_no_sig(rrset, &copy);
+	if (result != KNOT_EOK) {
+		return result;
+	}
+
+	result = knot_changeset_add_rrset(changeset, copy, KNOT_CHANGESET_REMOVE);
+	if (result != KNOT_EOK) {
+		knot_rrset_deep_free(&copy, 1);
+	}
+
+	return result;
+}
+
+static void delete_nsec3_chain_node_cb(knot_node_t **node_ptr, void *data)
+{
+	assert(node_ptr && *node_ptr);
+	assert(data);
+
+	knot_node_t *node = *node_ptr;
+	nsec3_chain_delete_data_t *params = (nsec3_chain_delete_data_t *)data;
+
+	if (params->result != KNOT_EOK) {
+		return;
+	}
+
+	int result = KNOT_EOK;
+
+	for (int i = 0; i < node->rrset_count; i++) {
+		const knot_rrset_t *rrset = node->rrset_tree[i];
+		result = copy_node_and_delete(rrset, params->changeset);
+		if (result != KNOT_EOK) {
+			break;
+		}
+
+		result = copy_node_and_delete(rrset->rrsigs, params->changeset);
+		if (result != KNOT_EOK) {
+			break;
+		}
+	}
+
+	params->result = result;
+}
+
+static int delete_nsec3_chain(const knot_zone_contents_t *zone,
+                              knot_changeset_t *changeset)
+{
+	assert(zone);
+	assert(changeset);
+
+	if (knot_zone_tree_is_empty(zone->nsec3_nodes)) {
+		return KNOT_EOK;
+	}
+
+	dbg_dnssec_detail("deleting NSEC3 chain\n");
+
+	nsec3_chain_delete_data_t cb_data = {
+		.changeset = changeset,
+		.result = KNOT_EOK
+	};
+
+	knot_zone_tree_apply(zone->nsec3_nodes, delete_nsec3_chain_node_cb,
+			     &cb_data);
+
+	return cb_data.result;
+}
+
+/* - helper functions ------------------------------------------------------ */
+
+/*!
+ * \brief Check if NSEC3 is enabled for given zone.
+ */
 bool is_nsec3_enabled(const knot_zone_contents_t *zone)
 {
 	if (!zone) {
@@ -795,8 +877,6 @@ bool is_nsec3_enabled(const knot_zone_contents_t *zone)
 	return zone->nsec3_params.algorithm != 0;
 }
 
-/* - helper functions ------------------------------------------------------ */
-
 /*!
  * \brief Get minimum TTL from zone SOA.
  * \note Value should be used for NSEC records.
@@ -873,13 +953,18 @@ int knot_zone_create_nsec_chain(const knot_zone_contents_t *zone,
 	}
 
 	int result;
+	bool nsec3_enabled = is_nsec3_enabled(zone);
 
-	if (is_nsec3_enabled(zone)) {
+	if (nsec3_enabled) {
 		result = create_nsec3_chain(zone, nsec_ttl, changeset);
 	} else {
 		result = create_nsec_chain(zone, nsec_ttl, changeset);
 	}
 
+	if (result == KNOT_EOK && !nsec3_enabled) {
+		result = delete_nsec3_chain(zone, changeset);
+	}
+
 	if (result != KNOT_EOK) {
 		return result;
 	}
diff --git a/src/libknot/zone/zone-tree.c b/src/libknot/zone/zone-tree.c
index 0a73c69440dc469f43310f91494f8b884c083a4d..c33731bc39b38a4775525d101443acdeeaaafd1f 100644
--- a/src/libknot/zone/zone-tree.c
+++ b/src/libknot/zone/zone-tree.c
@@ -56,6 +56,11 @@ size_t knot_zone_tree_weight(knot_zone_tree_t* tree)
 	return hattrie_weight(tree);
 }
 
+int knot_zone_tree_is_empty(knot_zone_tree_t *tree)
+{
+	return knot_zone_tree_weight(tree) == 0;
+}
+
 /*----------------------------------------------------------------------------*/
 
 int knot_zone_tree_insert(knot_zone_tree_t *tree, knot_node_t *node)
diff --git a/src/libknot/zone/zone-tree.h b/src/libknot/zone/zone-tree.h
index d9172ce4c6e9c4c8aae705294300daad0eeae4c0..8e15d88b9c663deed20e188a7846a131fdeac288 100644
--- a/src/libknot/zone/zone-tree.h
+++ b/src/libknot/zone/zone-tree.h
@@ -51,6 +51,15 @@ knot_zone_tree_t* knot_zone_tree_create();
  */
 size_t knot_zone_tree_weight(knot_zone_tree_t* tree);
 
+/*!
+ * \brief Checks if the zone tree is empty.
+ *
+ * \param tree Zone tree to check.
+ *
+ * \return Nonzero if the zone tree is empty.
+ */
+int knot_zone_tree_is_empty(knot_zone_tree_t *tree);
+
 /*!
  * \brief Inserts the given node into the zone tree.
  *