diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 55138d25906..12b2aed57cf 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -435,6 +435,8 @@ fetch_callback_dnskey(isc_task_t *task, isc_event_t *event) {
 			result = select_signing_key(val, rdataset);
 			if (result == ISC_R_SUCCESS) {
 				val->keyset = &val->frdataset;
+			} else {
+				val->failed = true;
 			}
 		}
 		result = validate_answer(val, true);
@@ -1174,6 +1176,8 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
 				goto done;
 			}
 			dst_key_free(&val->key);
+		} else {
+			break;
 		}
 		dns_rdata_reset(&rdata);
 		result = dns_rdataset_next(rdataset);
@@ -1291,13 +1295,15 @@ seek_dnskey(dns_validator_t *val) {
 				      "keyset with trust %s",
 				      dns_trust_totext(val->frdataset.trust));
 			result = select_signing_key(val, val->keyset);
-			if (result != ISC_R_SUCCESS) {
+			if (result == ISC_R_NOTFOUND) {
 				/*
-				 * Either the key we're looking for is not
-				 * in the rrset, or something bad happened.
-				 * Give up.
+				 * The key we're looking for is not
+				 * in the rrset
 				 */
 				result = DNS_R_CONTINUE;
+			} else if (result != ISC_R_SUCCESS) {
+				/* Something bad happened. Give up. */
+				break;
 			}
 		}
 		break;
@@ -1358,17 +1364,17 @@ compute_keytag(dns_rdata_t *rdata) {
 /*%
  * Is the DNSKEY rrset in val->event->rdataset self-signed?
  */
-static bool
+static isc_result_t
 selfsigned_dnskey(dns_validator_t *val) {
 	dns_rdataset_t *rdataset = val->event->rdataset;
 	dns_rdataset_t *sigrdataset = val->event->sigrdataset;
 	dns_name_t *name = val->event->name;
 	isc_result_t result;
 	isc_mem_t *mctx = val->view->mctx;
-	bool answer = false;
+	bool match = false;
 
 	if (rdataset->type != dns_rdatatype_dnskey) {
-		return false;
+		return DNS_R_NOKEYMATCH;
 	}
 
 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
@@ -1390,8 +1396,6 @@ selfsigned_dnskey(dns_validator_t *val) {
 		     result == ISC_R_SUCCESS;
 		     result = dns_rdataset_next(sigrdataset))
 		{
-			dst_key_t *dstkey = NULL;
-
 			dns_rdata_reset(&sigrdata);
 			dns_rdataset_current(sigrdataset, &sigrdata);
 			result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
@@ -1406,18 +1410,16 @@ selfsigned_dnskey(dns_validator_t *val) {
 
 			/*
 			 * If the REVOKE bit is not set we have a
-			 * theoretically self signed DNSKEY RRset.
-			 * This will be verified later.
+			 * theoretically self-signed DNSKEY RRset;
+			 * this will be verified later.
+			 *
+			 * We don't return the answer yet, though,
+			 * because we need to check the remaining keys
+			 * and possbly remove them if they're revoked.
 			 */
 			if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) {
-				answer = true;
-				continue;
-			}
-
-			result = dns_dnssec_keyfromrdata(name, &keyrdata, mctx,
-							 &dstkey);
-			if (result != ISC_R_SUCCESS) {
-				continue;
+				match = true;
+				break;
 			}
 
 			/*
@@ -1427,6 +1429,14 @@ selfsigned_dnskey(dns_validator_t *val) {
 			if (DNS_TRUST_PENDING(rdataset->trust) &&
 			    dns_view_istrusted(val->view, name, &key))
 			{
+				dst_key_t *dstkey = NULL;
+
+				result = dns_dnssec_keyfromrdata(
+					name, &keyrdata, mctx, &dstkey);
+				if (result != ISC_R_SUCCESS) {
+					break;
+				}
+
 				result = dns_dnssec_verify(
 					name, rdataset, dstkey, true,
 					val->view->maxbits, mctx, &sigrdata,
@@ -1439,6 +1449,8 @@ selfsigned_dnskey(dns_validator_t *val) {
 					 */
 					dns_view_untrust(val->view, name, &key);
 				}
+
+				dst_key_free(&dstkey);
 			} else if (rdataset->trust >= dns_trust_secure) {
 				/*
 				 * We trust this RRset so if the key is
@@ -1446,12 +1458,14 @@ selfsigned_dnskey(dns_validator_t *val) {
 				 */
 				dns_view_untrust(val->view, name, &key);
 			}
-
-			dst_key_free(&dstkey);
 		}
 	}
 
-	return answer;
+	if (!match) {
+		return DNS_R_NOKEYMATCH;
+	}
+
+	return ISC_R_SUCCESS;
 }
 
 /*%
@@ -1688,10 +1702,7 @@ check_signer(dns_validator_t *val, dns_rdata_t *keyrdata, uint16_t keyid,
 				val->event->name, keyrdata, val->view->mctx,
 				&dstkey);
 			if (result != ISC_R_SUCCESS) {
-				/*
-				 * This really shouldn't happen, but...
-				 */
-				continue;
+				return result;
 			}
 		}
 		result = verify(val, dstkey, &rdata, sig.keyid);
@@ -3051,11 +3062,22 @@ validator_start(isc_task_t *task, isc_event_t *event) {
 
 		INSIST(dns_rdataset_isassociated(val->event->rdataset));
 		INSIST(dns_rdataset_isassociated(val->event->sigrdataset));
-		if (selfsigned_dnskey(val)) {
+
+		result = selfsigned_dnskey(val);
+		switch (result) {
+		case ISC_R_SUCCESS:
 			result = validate_dnskey(val);
-		} else {
+			break;
+		case DNS_R_NOKEYMATCH:
 			result = validate_answer(val, false);
+			break;
+		default:
+			validator_log(val, ISC_LOG_INFO,
+				      "invalid selfsigned DNSKEY: %s",
+				      isc_result_totext(result));
+			goto cleanup;
 		}
+
 		if (result == DNS_R_NOVALIDSIG &&
 		    (val->attributes & VALATTR_TRIEDVERIFY) == 0)
 		{
@@ -3124,6 +3146,7 @@ validator_start(isc_task_t *task, isc_event_t *event) {
 		UNREACHABLE();
 	}
 
+cleanup:
 	if (result != DNS_R_WAIT) {
 		want_destroy = exit_check(val);
 		validator_done(val, result);
