diff --git a/services/cache/rrset.c b/services/cache/rrset.c
index ab4f4c8e0..404e11fbb 100644
--- a/services/cache/rrset.c
+++ b/services/cache/rrset.c
@@ -50,6 +50,7 @@
 #include "util/regional.h"
 #include "util/alloc.h"
 #include "util/net_help.h"
+#include "validator/val_utils.h"
 
 void
 rrset_markdel(void* key)
@@ -255,12 +256,43 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
 	return 0;
 }
 
+/** See if the name is a within signer authority */
+static int
+dname_subdomain_rrsig_signers(uint8_t* dname,
+	struct ub_packed_rrset_key* rrset)
+{
+	struct packed_rrset_data* d = (struct packed_rrset_data*)
+		rrset->entry.data;
+	size_t i;
+	if(!d || !d->rrsig_count)
+		return 0;
+	for(i=0; i<d->rrsig_count; i++) {
+		uint8_t* sname = NULL;
+		size_t slen = 0;
+		rrsig_get_signer(d->rr_data[d->count+i], d->rr_len[d->count+i],
+			&sname, &slen);
+		if(!sname || !slen)
+			return 0; /* malformed */
+		if(!dname_subdomain_c(dname, sname))
+			return 0; /* not a subdomain */
+	}
+	return 1;
+}
+
 void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache, 
 	struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
 	struct alloc_cache* alloc, time_t timenow)
 {
 	struct rrset_ref ref;
 	uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
+
+	/* See if the RRSIG signer name allows this wildcard,
+	 * the new rrset should fall within the zone of the RRSIG signer(s). */
+	if(!dname_subdomain_rrsig_signers(ce, rrset)) {
+		verbose(VERB_ALGO, "wildcard canonical parent outside signer authority");
+		return;
+	}
+
 	rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
 	if(!rrset) {
 		log_err("malloc failure in rrset_cache_update_wildcard");
diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c
index 9f27f9cc9..46e6ac16b 100644
--- a/validator/val_sigcrypt.c
+++ b/validator/val_sigcrypt.c
@@ -1666,6 +1666,13 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
 		return sec_status_bogus;
 	}
+	if((int)sig[2+3] < dname_signame_label_count(signer)) {
+		verbose(VERB_QUERY, "verify: RRSIG label count too low for signer");
+		*reason = "signature labelcount lower than signature signer";
+		if(reason_bogus)
+			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
+		return sec_status_bogus;
+	}
 
 	/* original ttl, always ok */
 
diff --git a/validator/val_utils.c b/validator/val_utils.c
index 8e4c91900..289078347 100644
--- a/validator/val_utils.c
+++ b/validator/val_utils.c
@@ -157,7 +157,7 @@ val_classify_response(uint16_t query_flags, struct query_info* origqinf,
 }
 
 /** Get signer name from RRSIG */
-static void
+void
 rrsig_get_signer(uint8_t* data, size_t len, uint8_t** sname, size_t* slen)
 {
 	/* RRSIG rdata is not allowed to be compressed, it is stored
diff --git a/validator/val_utils.h b/validator/val_utils.h
index e0c649902..f3750742b 100644
--- a/validator/val_utils.h
+++ b/validator/val_utils.h
@@ -438,4 +438,8 @@ struct dns_msg* val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen,
 int derive_cname_from_dname(struct ub_packed_rrset_key* cname,
 	struct ub_packed_rrset_key* dname, uint8_t* out, size_t outlen);
 
+/** Get signer name from RRSIG, sname is NULL if malformed. */
+void rrsig_get_signer(uint8_t* data, size_t len, uint8_t** sname,
+	size_t* slen);
+
 #endif /* VALIDATOR_VAL_UTILS_H */
diff --git a/validator/validator.c b/validator/validator.c
index e7992b6e3..a72aa9c6a 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -1043,6 +1043,10 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
 	uint8_t* wc = NULL;
 	size_t wl;
 	int wc_cached = 0;
+	int wc_to_cache = 0;
+	uint8_t* cache_wc = NULL;
+	size_t cache_wl = 0;
+	struct ub_packed_rrset_key* cache_s = NULL;
 	int wc_NSEC_ok = 0;
 	int nsec3s_seen = 0;
 	size_t i;
@@ -1065,8 +1069,11 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
 			return;
 		}
 		if(wc && !wc_cached && env->cfg->aggressive_nsec) {
-			rrset_cache_update_wildcard(env->rrset_cache, s, wc, wl,
-				env->alloc, *env->now);
+			/* Postpone cache adjust until proof has succeeded. */
+			wc_to_cache = 1;
+			cache_wc = wc;
+			cache_wl = wl;
+			cache_s = s;
 			wc_cached = 1;
 		}
 
@@ -1128,6 +1135,10 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
 		update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
 		return;
 	}
+	if(wc_to_cache) {
+		rrset_cache_update_wildcard(env->rrset_cache, cache_s,
+			cache_wc, cache_wl, env->alloc, *env->now);
+	}
 
 	verbose(VERB_ALGO, "Successfully validated positive response");
 	chase_reply->security = sec_status_secure;
