diff --git a/iterator/iterator.c b/iterator/iterator.c
index cc38348b3..78cd9485b 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -81,7 +81,8 @@ int BLACKLIST_PENALTY = (120000*4);
 /** Timeout when only a single probe query per IP is allowed. */
 int PROBE_MAXRTO = PROBE_MAXRTO_DEFAULT; /* in msec */
 
-static void target_count_increase_nx(struct iter_qstate* iq, int num);
+static void target_count_increase_nx(struct module_qstate* qstate,
+	struct iter_qstate* iq, int num);
 
 int 
 iter_init(struct module_env* env, int id)
@@ -250,7 +251,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
 		if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) &&
 			(dpns->got6 == 2 || !ie->supports_ipv6)) {
 			dpns->resolved = 1; /* mark as failed */
-			target_count_increase_nx(super_iq, 1);
+			target_count_increase_nx(super, super_iq, 1);
 		}
 	}
 	if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
@@ -734,7 +735,7 @@ is_caps_whitelisted(struct iter_env* ie, struct iter_qstate* iq)
  * created for the parent query.
  */
 static void
-target_count_create(struct iter_qstate* iq)
+target_count_create(struct module_qstate* qstate, struct iter_qstate* iq)
 {
 	if(!iq->target_count) {
 		iq->target_count = (int*)calloc(TARGET_COUNT_MAX, sizeof(int));
@@ -742,33 +743,57 @@ target_count_create(struct iter_qstate* iq)
 		if(iq->target_count) {
 			iq->target_count[TARGET_COUNT_REF] = 1;
 			iq->nxns_dp = (uint8_t**)calloc(1, sizeof(uint8_t*));
+			/* continue global quota from where it was. */
+			if(qstate->global_quota_reached >
+				iq->target_count[TARGET_COUNT_GLOBAL_QUOTA])
+				iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] =
+					qstate->global_quota_reached;
 		}
 	}
 }
 
 static void
-target_count_increase(struct iter_qstate* iq, int num)
+target_count_store(struct module_qstate* qstate, struct iter_qstate* iq)
 {
-	target_count_create(iq);
+	if(iq->target_count) {
+		/* By storing the global quota counter, it stays
+		 * there to be picked up if the module is restarted,
+		 * eg. due to a validator retry, and then the
+		 * target_count_create routine picks it up. */
+		if(iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] >
+			qstate->global_quota_reached)
+			qstate->global_quota_reached =
+			  iq->target_count[TARGET_COUNT_GLOBAL_QUOTA];
+	}
+}
+
+static void
+target_count_increase(struct module_qstate* qstate,
+	struct iter_qstate* iq, int num)
+{
+	target_count_create(qstate, iq);
 	if(iq->target_count)
 		iq->target_count[TARGET_COUNT_QUERIES] += num;
 	iq->dp_target_count++;
 }
 
 static void
-target_count_increase_nx(struct iter_qstate* iq, int num)
+target_count_increase_nx(struct module_qstate* qstate,
+	struct iter_qstate* iq, int num)
 {
-	target_count_create(iq);
+	target_count_create(qstate, iq);
 	if(iq->target_count)
 		iq->target_count[TARGET_COUNT_NX] += num;
 }
 
 static void
-target_count_increase_global_quota(struct iter_qstate* iq, int num)
+target_count_increase_global_quota(struct module_qstate* qstate,
+	struct iter_qstate* iq, int num)
 {
-	target_count_create(iq);
+	target_count_create(qstate, iq);
 	if(iq->target_count)
 		iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
+	target_count_store(qstate, iq);
 }
 
 /**
@@ -861,7 +886,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
 		subiq = (struct iter_qstate*)subq->minfo[id];
 		memset(subiq, 0, sizeof(*subiq));
 		subiq->num_target_queries = 0;
-		target_count_create(iq);
+		target_count_create(qstate, iq);
 		subiq->target_count = iq->target_count;
 		if(iq->target_count) {
 			iq->target_count[TARGET_COUNT_REF] ++; /* extra reference */
@@ -2234,7 +2259,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
 			return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
 		}
 		iq->num_target_queries += qs;
-		target_count_increase(iq, qs);
+		target_count_increase(qstate, iq, qs);
 		if(qs != 0) {
 			qstate->ext_state[id] = module_wait_subquery;
 			return 0; /* and wait for them */
@@ -2290,7 +2315,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
 				 * lookups at a time. */
 				verbose(VERB_ALGO, "try parent-side glue lookup");
 				iq->num_target_queries += query_count;
-				target_count_increase(iq, query_count);
+				target_count_increase(qstate, iq, query_count);
 				qstate->ext_state[id] = module_wait_subquery;
 				return 0;
 			}
@@ -2310,7 +2335,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
 		if(query_count != 0) { /* suspend to await results */
 			verbose(VERB_ALGO, "try parent-side glue lookup");
 			iq->num_target_queries += query_count;
-			target_count_increase(iq, query_count);
+			target_count_increase(qstate, iq, query_count);
 			qstate->ext_state[id] = module_wait_subquery;
 			return 0;
 		}
@@ -2788,7 +2813,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
 			return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
 		}
 		iq->num_target_queries += extra;
-		target_count_increase(iq, extra);
+		target_count_increase(qstate, iq, extra);
 		if(iq->num_target_queries > 0) {
 			/* wait to get all targets, we want to try em */
 			verbose(VERB_ALGO, "wait for all targets for fallback");
@@ -2839,7 +2864,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
 		/* errors ignored, these targets are not strictly necessary for
 		 * this result, we do not have to reply with SERVFAIL */
 		iq->num_target_queries += extra;
-		target_count_increase(iq, extra);
+		target_count_increase(qstate, iq, extra);
 	}
 
 	/* Add the current set of unused targets to our queue. */
@@ -2962,7 +2987,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
 						LDNS_RCODE_SERVFAIL);
 				}
 				iq->num_target_queries += qs;
-				target_count_increase(iq, qs);
+				target_count_increase(qstate, iq, qs);
 			}
 			/* Since a target query might have been made, we 
 			 * need to check again. */
@@ -3022,7 +3047,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
 		* this result, we do not have to reply with SERVFAIL */
 		if(extra > 0) {
 			iq->num_target_queries += extra;
-			target_count_increase(iq, extra);
+			target_count_increase(qstate, iq, extra);
 			check_waiting_queries(iq, qstate, id);
 			/* undo qname minimise step because we'll get back here
 			 * to do it again */
@@ -3035,7 +3060,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
 		}
 	}
 
-	target_count_increase_global_quota(iq, 1);
+	target_count_increase_global_quota(qstate, iq, 1);
 	if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
 		> MAX_GLOBAL_QUOTA) {
 		char s[LDNS_MAX_DOMAINLEN];
@@ -3879,7 +3904,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
 			/* no new addresses, increase the nxns counter, like
 			 * this could be a list of wildcards with no new
 			 * addresses */
-			target_count_increase_nx(foriq, 1);
+			target_count_increase_nx(qstate, foriq, 1);
 		}
 		verbose(VERB_ALGO, "added target response");
 		delegpt_log(VERB_ALGO, foriq->dp);
@@ -3891,7 +3916,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
 			dpns->resolved = 1; /* fail the target */
 			/* do not count cached answers */
 			if(qstate->reply_origin && qstate->reply_origin->len != 0) {
-				target_count_increase_nx(foriq, 1);
+				target_count_increase_nx(qstate, foriq, 1);
 			}
 		}
 	}
@@ -4116,6 +4141,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
 			iter_store_parentside_neg(qstate->env, &qstate->qinfo,
 				iq->deleg_msg?iq->deleg_msg->rep:
 				(iq->response?iq->response->rep:NULL));
+	target_count_store(qstate, iq);
 	if(!iq->response) {
 		verbose(VERB_ALGO, "No response is set, servfail");
 		errinf(qstate, "(no response found at query finish)");
@@ -4531,6 +4557,7 @@ iter_clear(struct module_qstate* qstate, int id)
 	iq = (struct iter_qstate*)qstate->minfo[id];
 	if(iq) {
 		outbound_list_clear(&iq->outlist);
+		target_count_store(qstate, iq);
 		if(iq->target_count && --iq->target_count[TARGET_COUNT_REF] == 0) {
 			free(iq->target_count);
 			if(*iq->nxns_dp) free(*iq->nxns_dp);
diff --git a/util/module.h b/util/module.h
index a6fa6be90..75c3675e1 100644
--- a/util/module.h
+++ b/util/module.h
@@ -721,6 +721,12 @@ struct module_qstate {
 
 	/** whether the reply should be dropped */
 	int is_drop;
+	/** the global quota that was reached, by one of the modules.
+	 * So that continued counting can go on from that point. */
+	int global_quota_reached;
+	/** the global quota that a query started with, it is a subquery,
+	 * so that calling mesh states can see the increase. */
+	int global_quota_started;
 };
 
 /** 
diff --git a/validator/validator.c b/validator/validator.c
index e7992b6e3..09e952e65 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -517,6 +517,14 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
 		/* add our blacklist to the query blacklist */
 		sock_list_merge(&(*newq)->blacklist, (*newq)->region,
 			vq->chain_blacklist);
+		/* start its global quota counter where this one is. */
+		if(qstate->global_quota_reached >
+			(*newq)->global_quota_reached) {
+			(*newq)->global_quota_started =
+				qstate->global_quota_reached;
+			(*newq)->global_quota_reached =
+				qstate->global_quota_reached;
+		}
 	}
 	qstate->ext_state[id] = module_wait_subquery;
 	return 1;
@@ -3536,6 +3544,11 @@ val_inform_super(struct module_qstate* qstate, int id,
 		verbose(VERB_ALGO, "super: has no validator state");
 		return;
 	}
+	/* Pick up the global quota limit from the subquery. */
+	if(qstate->global_quota_reached > qstate->global_quota_started) {
+		super->global_quota_reached += qstate->global_quota_reached -
+			qstate->global_quota_started;
+	}
 	if(vq->wait_prime_ta) {
 		vq->wait_prime_ta = 0;
 		process_prime_response(super, vq, id, qstate->return_rcode,
