diff --git a/lib/layer/validate.c b/lib/layer/validate.c
index e60252870bc467032bd36e174a1bdf5734faa601..314d901e1aa7983484d8167eeae1cb8bc9bcc8c3 100644
--- a/lib/layer/validate.c
+++ b/lib/layer/validate.c
@@ -358,9 +358,11 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
 	}
 
 	bool has_nsec3 = _knot_pkt_has_type(pkt, KNOT_RRTYPE_NSEC3);
+	uint8_t pkt_rcode = knot_wire_get_rcode(pkt->wire);
 
 	/* Validate non-existence proof if not positive answer. */
-	if (knot_wire_get_rcode(pkt->wire) == KNOT_RCODE_NXDOMAIN) {
+	if (pkt_rcode == KNOT_RCODE_NXDOMAIN) {
+		/* @todo If knot_pkt_qname(pkt) is used instead of qry->sname then the test crash. */
 		if (!has_nsec3) {
 			ret = kr_nsec_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname, &req->pool);
 		} else {
@@ -373,6 +375,39 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt)
 		}
 	}
 
+	{
+		knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_ANSWER);
+		uint16_t answer_count = sec ? sec->count : 0;
+
+		/* Validate no data response. */
+		if ((pkt_rcode == KNOT_RCODE_NOERROR) && (!answer_count) &&
+		    (KNOT_WIRE_AA_MASK & knot_wire_get_flags1(pkt->wire))) {
+			/* @todo
+			 * ? quick mechanism to determine which check to preform first
+			 * ? merge the functionality together to share code/resources
+			 */
+			if (!has_nsec3) {
+				ret = kr_nsec_no_data_response_check(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
+				if (ret != 0) {
+					ret = kr_nsec_wildcard_no_data_response_check(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
+				}
+				if (ret != 0) {
+					ret = kr_nsec_empty_nonterminal_response_check(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt));
+				}
+			} else {
+				ret = kr_nsec3_no_data_response_check(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
+				if (ret != 0) {
+					ret = kr_nsec3_wildcard_no_data_response_check(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt));
+				}
+			}
+			if (ret != 0) {
+				DEBUG_MSG(qry, "<= bad no data response proof\n");
+				qry->flags |= QUERY_DNSSEC_BOGUS;
+				return KNOT_STATE_FAIL;
+			}
+		}
+	}
+
 	/* Check whether the current zone cut holds keys that can be used
 	 * for validation (i.e. RRSIG signer name matches key owner).
 	 */