diff --git a/src/knot/zone/zone-dump.c b/src/knot/zone/zone-dump.c
index 4d9f3f56bff9d0bc60c89234c36873f5dc33cd36..f22c19c15f09f1743c5eb5a0c083f8b863477b45 100644
--- a/src/knot/zone/zone-dump.c
+++ b/src/knot/zone/zone-dump.c
@@ -360,6 +360,11 @@ static int knot_rdata_dump_binary(knot_rdata_t *rdata,
 				rdata->items[i].dname) {
 				wildcard = rdata->items[i].dname->node->owner;
 			}
+			
+			dbg_zdump_detail("zdump: dump_rdata: "
+			                 "Writing dname: %s.\n",
+			                 knot_dname_to_str(
+						rdata->items[i].dname));
 
 			if (use_ids) {
 				/* Write ID. */
@@ -392,6 +397,8 @@ static int knot_rdata_dump_binary(knot_rdata_t *rdata,
 			/*! \todo Does not have to be so complex.
 			 *        Create extra variable. */
 			if (rdata->items[i].dname->node != NULL && !wildcard) {
+				dbg_zdump("zdump: dump_rdata: "
+				          "This dname is in the zone.\n");
 				if (!write_wrapper((uint8_t *)"\1",
 				                   sizeof(uint8_t), 1, fd,
 				                   stream, max_size,
@@ -401,6 +408,8 @@ static int knot_rdata_dump_binary(knot_rdata_t *rdata,
 					return KNOT_ERROR;
 				}
 			} else {
+				dbg_zdump("zdump: dump_rdata: "
+				          "This dname is not in the zone.\n");
 				if (!write_wrapper((uint8_t *)"\0",
 				                   sizeof(uint8_t),
 				                   1, fd,
@@ -423,6 +432,9 @@ static int knot_rdata_dump_binary(knot_rdata_t *rdata,
 				}
 				
 				uint32_t wildcard_id = wildcard->id;
+				dbg_zdump("zdump: dump_rdata: "
+				          "This dname is covered by wc (%s).\n",
+				          knot_dname_to_str(wildcard));
 				if (!write_wrapper(&wildcard_id,
 				                   sizeof(wildcard_id), 1,
 				                   fd, stream, max_size,
diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c
index 8832a795a8c1feec9a56d20e86a62ca3a136766c..bd777ccfd0b06d3d9bdbcc52eacc252f7f7234e9 100644
--- a/src/knot/zone/zone-load.c
+++ b/src/knot/zone/zone-load.c
@@ -285,6 +285,7 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
 			/*!< \todo #1686
 			 * Refactor these variables, some might be too big.
 			 */
+			
 
 			uint32_t dname_id = 0;
 			uint8_t has_wildcard = 0;
@@ -306,6 +307,11 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
 			} else {
 				items[i].dname = read_dname_with_id(f);
 			}
+			
+			dbg_zload_detail("zload: load_rdata: "
+			                 "Loading dname: %s.\n",
+			              knot_dname_to_str(items[i].dname));
+
 
 			if(!fread_wrapper(&in_the_zone, sizeof(in_the_zone),
 			               1, f)) {
@@ -322,6 +328,23 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
 				          "Cannot read wildcard bit.\n");
 				return NULL;
 			}
+			
+			dbg_zload_detail("zload: load_rdata: Has wildcard: "
+			                 "%d\n", has_wildcard);
+			
+			if (use_ids && !in_the_zone) {
+				dbg_zload_detail("zload: load_rdata: "
+				                 "Freeing node owned by: %s\n",
+				                 knot_dname_to_str(
+							items[i].dname));
+				/* destroy the node */
+				assert(!in_the_zone);
+				if (items[i].dname->node != NULL) {
+					knot_node_free(&items[i].dname->node,
+					               0);
+				}
+				/* Also sets node to NULL! */
+			}
 
 			if (use_ids && has_wildcard) {
 				if(!fread_wrapper(&dname_id, sizeof(dname_id),
@@ -332,16 +355,14 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
 					          "Cannot read wc ID.\n");
 					return NULL;
 				}
+				dbg_zload_detail("zload: load_rdata: "
+				                 "Wildcard: %s\n",
+				                 knot_dname_to_str(
+				                         id_array[dname_id]));
 				items[i].dname->node =
 					id_array[dname_id]->node;
-			} else if (use_ids && !in_the_zone) {
-				/* destroy the node */
-				if (id_array[dname_id]->node != NULL) {
-					knot_node_free(&id_array[dname_id]->
-							 node, 0);
-				}
-				/* Also sets node to NULL! */
 			}
+			
 			assert(items[i].dname);
 		} else {
 			if (!fread_wrapper(&raw_data_length,
@@ -1190,6 +1211,9 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 	for (uint i = 1; i < node_count; i++) {
 		tmp_node = knot_load_node(f, id_array);
 		if (tmp_node != NULL) {
+			dbg_zload_detail("zload: load: Adding node owned by: "
+			                 "%s\n.",
+			                 knot_dname_to_str(tmp_node->owner));
 			if (knot_zone_contents_add_node(contents, tmp_node,
 			                                  0, 0, 0) != 0) {
 				cleanup_id_array(id_array, 1,
@@ -1200,6 +1224,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
 				          "to zone.\n");
 				return NULL;
 			}
+			
 			if (knot_dname_is_wildcard(tmp_node->owner)) {
 				find_and_set_wildcard_child(contents,
 				                            tmp_node, 0);
diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index b437f1937632b4e0793a438070bae6882db14ca6..cf6522f0ddf9c6e943acc3874fd5cb4d412a32d0 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -594,14 +594,26 @@ static int ns_put_additional_for_rrset(knot_packet_t *resp,
 		dbg_ns_verb("Getting name from RDATA, type %s..\n",
 		            knot_rrtype_to_string(knot_rrset_type(rrset)));
 		dname = knot_rdata_get_name(rdata, knot_rrset_type(rrset));
+
+dbg_ns_exec_detail(
+		char *name = knot_dname_to_str(dname);
+		dbg_ns_detail("Name: %s\n", name);
+		free(name);
+);
 		assert(dname != NULL);
 		node = knot_dname_node(dname);
 		
+		dbg_ns_detail("Node saved in RDATA dname: %p\n", node);
 		if (node != NULL && node->owner != dname) {
-			// the stored node should be the closest encloser
-			assert(knot_dname_is_subdomain(dname, node->owner));
-			// try the wildcard child, if any
-			node = knot_node_wildcard_child(node);
+			// the stored node should be the wildcard covering the
+			// name
+			dbg_ns_detail("Node is wildcard.\n");
+			assert(knot_dname_is_wildcard(knot_node_owner(node)));
+
+//			// the stored node should be the closest encloser
+//			assert(knot_dname_is_subdomain(dname, node->owner));
+//			// try the wildcard child, if any
+//			node = knot_node_wildcard_child(node);
 		}
 
 		knot_rrset_t *rrset_add;
diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c
index abf9c3c9dd856e628e3fac5a6157eaf8a1a16ea9..17ebd340c9d63804a14bb4006c536a27c5ffedf7 100644
--- a/src/libknot/zone/zone-contents.c
+++ b/src/libknot/zone/zone-contents.c
@@ -260,6 +260,239 @@ dbg_zone_exec_detail(
 	return KNOT_EOK;
 }
 
+/*----------------------------------------------------------------------------*/
+
+static const knot_node_t *knot_zone_contents_find_wildcard_child(
+        knot_zone_contents_t *zone, const knot_node_t *closest_encloser)
+{
+	assert(zone != NULL);
+	assert(closest_encloser != NULL);
+
+	knot_dname_t *tmp = knot_dname_new_from_str("*", 1, NULL);
+	CHECK_ALLOC(tmp, NULL);
+
+	knot_dname_t *wildcard = knot_dname_cat(tmp, knot_node_owner(
+	                                                closest_encloser));
+	if (wildcard == NULL) {
+		free(tmp);
+		return NULL;
+	}
+
+	assert(wildcard == tmp);
+
+dbg_zone_exec_detail(
+	char *name = knot_dname_to_str(knot_node_owner(closest_encloser));
+	char *name2 = knot_dname_to_str(wildcard);
+	dbg_zone_detail("Searching for wildcard child of %s (%s)\n", name,
+	                name2);
+	free(name);
+	free(name2);
+);
+
+	const knot_node_t *found = NULL, *ce = NULL, *prev = NULL;
+	int ret = knot_zone_contents_find_dname(zone, wildcard, &found, &ce,
+	                                        &prev);
+
+	knot_dname_free(&wildcard);
+
+	if (ret != KNOT_ZONE_NAME_FOUND) {
+		return NULL;
+	} else {
+		return found;
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief Adjusts one RDATA item by replacing domain name by one present in the
+ *        zone.
+ *
+ * This function tries to find the domain name in the zone. If the name is not
+ * in the zone, it does nothing. If it is there, it destroys the domain name
+ * stored in the RDATA item and replaces it by pointer to the domain name from
+ * the zone.
+ *
+ * \warning Call this function only with RDATA items which store domain names,
+ *          otherwise the behaviour is undefined.
+ *
+ * \param rdata RDATA where the item is located.
+ * \param zone Zone to which the RDATA belongs.
+ * \param pos Position of the RDATA item in the RDATA.
+ */
+static void knot_zone_contents_adjust_rdata_item(knot_rdata_t *rdata,
+                                                 knot_zone_contents_t *zone,
+                                                 knot_node_t *node, int pos)
+{
+	const knot_rdata_item_t *dname_item = knot_rdata_item(rdata, pos);
+
+	assert(dname_item);
+
+	if (dname_item != NULL) {
+		knot_dname_t *dname = dname_item->dname;
+
+		if (knot_dname_node(dname) != NULL
+		    || !knot_dname_is_subdomain(dname, knot_node_owner(
+		                              knot_zone_contents_apex(zone)))) {
+			// The name's node is either already set
+			// or the name does not belong to the zone
+			dbg_zone_detail("Name's node either set or the name "
+			                "does not belong to the zone (%p).\n",
+			                knot_dname_node(dname));
+			return;
+		}
+
+		const knot_node_t *n = NULL;
+		const knot_node_t *closest_encloser = NULL;
+		const knot_node_t *prev = NULL;
+
+		int ret = knot_zone_contents_find_dname(zone, dname, &n,
+		                                      &closest_encloser, &prev);
+
+		if (ret == KNOT_EBADARG || ret == KNOT_EBADZONE) {
+			// TODO: do some cleanup if needed
+			dbg_zone_detail("Failed to find the name in zone: %s\n",
+			                knot_strerror(ret));
+			return;
+		}
+
+		assert(ret != KNOT_ZONE_NAME_FOUND || n == closest_encloser);
+
+		if (ret != KNOT_ZONE_NAME_FOUND && (closest_encloser != NULL)) {
+			/*!
+			 * \note There is no need to set closer encloser to the
+			 *       name. We may find the possible wildcard child
+			 *       right away.
+			 *       Having the closest encloser saved in the dname
+			 *       would disrupt the query processing algorithms
+			 *       anyway.
+			 */
+
+			dbg_zone_verb("Trying to find wildcard child.\n");
+
+			n = knot_zone_contents_find_wildcard_child(zone,
+			                                      closest_encloser);
+			if (n != NULL) {
+				dname->node = (knot_node_t *)n;
+				dbg_zone_exec_detail(
+					char *name = knot_dname_to_str(
+					                    knot_node_owner(n));
+					char *name2 = knot_dname_to_str(dname);
+					dbg_zone_detail("Set wildcard node %s "
+					                "to RDATA dname %s.\n",
+					                name, name2);
+					free(name);
+					free(name2);
+				);
+			}
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief Adjusts all RDATA in the given RRSet by replacing domain names by ones
+ *        present in the zone.
+ *
+ * This function selects the RDATA items containing a domain name (according to
+ * RR type descriptor of the RRSet's type and adjusts the item using
+ * knot_zone_adjust_rdata_item().
+ *
+ * \param rrset RRSet to adjust RDATA in.
+ * \param zone Zone to which the RRSet belongs.
+ */
+static void knot_zone_contents_adjust_rdata_in_rrset(knot_rrset_t *rrset,
+                                                     knot_zone_contents_t *zone,
+                                                     knot_node_t *node)
+{
+	uint16_t type = knot_rrset_type(rrset);
+
+	knot_rrtype_descriptor_t *desc =
+		knot_rrtype_descriptor_by_type(type);
+	assert(desc);
+
+	knot_rdata_t *rdata_first = knot_rrset_get_rdata(rrset);
+	knot_rdata_t *rdata = rdata_first;
+
+	if (rdata == NULL) {
+		return;
+	}
+
+	while (rdata->next != rdata_first) {
+		for (int i = 0; i < rdata->count; ++i) {
+			if (desc->wireformat[i]
+			    == KNOT_RDATA_WF_COMPRESSED_DNAME
+			    || desc->wireformat[i]
+			       == KNOT_RDATA_WF_UNCOMPRESSED_DNAME
+			    || desc->wireformat[i]
+			       == KNOT_RDATA_WF_LITERAL_DNAME) {
+				dbg_zone("Adjusting domain name at "
+				  "position %d of RDATA of record with owner "
+				  "%s and type %s.\n",
+				  i, rrset->owner->name,
+				  knot_rrtype_to_string(type));
+
+				knot_zone_contents_adjust_rdata_item(rdata,
+				                                     zone, node,
+				                                     i);
+			}
+		}
+		rdata = rdata->next;
+	}
+
+	for (int i = 0; i < rdata->count; ++i) {
+		if (desc->wireformat[i]
+		    == KNOT_RDATA_WF_COMPRESSED_DNAME
+		    || desc->wireformat[i]
+		       == KNOT_RDATA_WF_UNCOMPRESSED_DNAME
+		    || desc->wireformat[i]
+		       == KNOT_RDATA_WF_LITERAL_DNAME) {
+			dbg_zone("Adjusting domain name at "
+			  "position %d of RDATA of record with owner "
+			  "%s and type %s.\n",
+			  i, rrset->owner->name,
+			  knot_rrtype_to_string(type));
+
+			knot_zone_contents_adjust_rdata_item(rdata, zone, node,
+			                                     i);
+		}
+	}
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+ * \brief Adjusts all RRSets in the given node by replacing domain names in
+ *        RDATA by ones present in the zone.
+ *
+ * This function just calls knot_zone_adjust_rdata_in_rrset() for all RRSets
+ * in the node (including all RRSIG RRSets).
+ *
+ * \param node Zone node to adjust the RRSets in.
+ * \param zone Zone to which the node belongs.
+ */
+static void knot_zone_contents_adjust_rrsets(knot_node_t *node,
+                                             knot_zone_contents_t *zone)
+{
+	knot_rrset_t **rrsets = knot_node_get_rrsets(node);
+	short count = knot_node_rrset_count(node);
+
+	assert(count == 0 || rrsets != NULL);
+
+	for (int r = 0; r < count; ++r) {
+		assert(rrsets[r] != NULL);
+		dbg_zone("Adjusting next RRSet.\n");
+		knot_zone_contents_adjust_rdata_in_rrset(rrsets[r], zone,
+		                                           node);
+		knot_rrset_t *rrsigs = rrsets[r]->rrsigs;
+		if (rrsigs != NULL) {
+			dbg_zone("Adjusting next RRSIGs.\n");
+			knot_zone_contents_adjust_rdata_in_rrset(rrsigs, zone,
+			                                         node);
+		}
+	}
+
+	free(rrsets);
+}
 /*----------------------------------------------------------------------------*/
 /*!
  * \brief Adjusts zone node for faster query processing.
@@ -288,12 +521,8 @@ dbg_zone_exec_verb(
 );
 
 	// adjust domain names in RDATA
-	/*!
-	 * \note This is unnecessary, as the code in adjust_rdata_item() is not
-	 *       reachable anyway. However, it's not clear why we disabled the
-	 *       code, so this would need further investigation.
-	 */
-	//knot_zone_contents_adjust_rrsets(node, zone);
+	/*! \note Enabled again after a LONG time. Should test thoroughly. */
+	knot_zone_contents_adjust_rrsets(node, zone);
 
 dbg_zone_exec_detail(
 	if (knot_node_parent(node)) {
@@ -1725,19 +1954,23 @@ dbg_zone_exec_detail(
 		free(name_str2);
 	}
 );
-
-	*closest_encloser = *node;
-
 	// there must be at least one node with domain name less or equal to
 	// the searched name if the name belongs to the zone (the root)
-	if (*node == NULL) {
+	if (*node == NULL && *previous == NULL) {
 		return KNOT_EBADZONE;
 	}
 
-	// TODO: this could be replaced by saving pointer to closest encloser
-	//       in node
+	/* This function was quite out of date. The find_in_tree() function
+	 * may return NULL in the 'found' field, so we cannot search for the
+	 * closest encloser from this node.
+	 */
+
+	if (exact_match) {
+		*closest_encloser = *node;
+	} else {
+		*closest_encloser = *previous;
+		assert(*closest_encloser != NULL);
 
-	if (!exact_match) {
 		int matched_labels = knot_dname_matched_labels(
 				knot_node_owner((*closest_encloser)), name);
 		while (matched_labels < knot_dname_label_count(