diff --git a/lib/resolve.c b/lib/resolve.c
index cc031b12e4b9b811e1ca709987c7c92ba19d34fe..f415b9e163755cab9479097fa67d696f2d47ae7e 100644
--- a/lib/resolve.c
+++ b/lib/resolve.c
@@ -138,10 +138,15 @@ static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param)
 	if (!next) {
 		return kr_error(ENOMEM);
 	}
-	/* At the root level with no NS addresses, revert to SBELT. */
+	/* At the root level with no NS addresses, add SBELT subrequest. */
 	int ret = 0;
 	if (qry->zone_cut.name[0] == '\0') {
-		ret = kr_zonecut_set_sbelt(ctx, &qry->zone_cut);
+		ret = kr_zonecut_set_sbelt(ctx, &next->zone_cut);
+		if (ret == 0) { /* Copy TA and key since it's the same cut to avoid lookup. */
+			kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut);
+			kr_zonecut_set_sbelt(ctx, &qry->zone_cut); /* Add SBELT to parent in case query fails. */
+			qry->flags |= QUERY_NO_THROTTLE; /* Pick even bad SBELT servers */
+		}
 	} else {
 		next->flags |= QUERY_AWAIT_CUT;
 	}
@@ -422,7 +427,7 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot
 		WITH_DEBUG {
 		char qname_str[KNOT_DNAME_MAXLEN];
 		knot_dname_to_str(qname_str, qry->zone_cut.name, sizeof(qname_str));
-		DEBUG_MSG(">< TA: using '%s'\n", qname_str);
+		DEBUG_MSG(">< TA: '%s'\n", qname_str);
 		}
 	}
 	if (want_secured && !qry->zone_cut.trust_anchor) {
@@ -504,6 +509,11 @@ ns_election:
 	if (qry->flags & (QUERY_AWAIT_IPV4|QUERY_AWAIT_IPV6)) {
 		kr_nsrep_elect_addr(qry, request->ctx);
 	} else if (!(qry->flags & QUERY_TCP)) { /* Keep address when TCP retransmit. */
+		/* Root DNSKEY must be fetched from the hints to avoid chicken and egg problem. */
+		if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) {
+			DEBUG_MSG("=> priming root DNSKEY\n");
+			kr_zonecut_set_sbelt(request->ctx, &qry->zone_cut);
+		}
 		kr_nsrep_elect(qry, request->ctx);
 		if (qry->ns.score > KR_NS_MAX_SCORE) {
 			DEBUG_MSG("=> no valid NS left\n");
@@ -541,8 +551,9 @@ ns_election:
 			break;
 		}
 		inet_ntop(addr->sa_family, kr_nsrep_inaddr(qry->ns.addr[i]), ns_str, sizeof(ns_str));
-		DEBUG_MSG("%c> querying: '%s' score: %u zone cut: '%s' m12n: '%s' type: '%s'\n",
-		          i == 0 ? '=' : '+', ns_str, qry->ns.score, zonecut_str, qname_str, type_str);
+		DEBUG_MSG("%s: '%s' score: %u zone cut: '%s' m12n: '%s' type: '%s'\n",
+		          i == 0 ? "=> querying" : "   optional",
+		          ns_str, qry->ns.score, zonecut_str, qname_str, type_str);
 	}
 	}
 
diff --git a/lib/zonecut.c b/lib/zonecut.c
index 36046c391d772f845b31de834db38b81aad70bdd..b55688781771e63580bc747612331173ea8dc4b8 100644
--- a/lib/zonecut.c
+++ b/lib/zonecut.c
@@ -276,9 +276,6 @@ int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut)
 			}
 		}
 	}
-
-	/* Set trust anchor. */
-	knot_rrset_free(&cut->trust_anchor, cut->pool);
 	return ret;
 }