diff --git a/lib/layer/pktcache.c b/lib/layer/pktcache.c
index 8c866e4ec3cd9679a5b0aabdfb07f770f9265f71..46f5a3177db3751496346a93a4d8e21ef7409e2d 100644
--- a/lib/layer/pktcache.c
+++ b/lib/layer/pktcache.c
@@ -97,7 +97,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
 	struct kr_request *req = ctx->data;
 	struct kr_rplan *rplan = &req->rplan;
 	struct kr_query *qry = kr_rplan_current(rplan);
-	if (!qry || ctx->state & (KNOT_STATE_DONE|KNOT_STATE_FAIL)) {
+	if (ctx->state & (KNOT_STATE_FAIL|KNOT_STATE_DONE) || (qry->flags & QUERY_NO_CACHE)) {
 		return ctx->state; /* Already resolved/failed */
 	}
 	if (qry->ns.addr.ip.sa_family != AF_UNSPEC) {
diff --git a/lib/layer/rrcache.c b/lib/layer/rrcache.c
index 5b32f4a0cb8c5bedf5199df3bb6a60ee16686b49..d440fdd47505249f68849eb149d65a4ce4dfe205 100644
--- a/lib/layer/rrcache.c
+++ b/lib/layer/rrcache.c
@@ -55,11 +55,7 @@ static int loot_rr(struct kr_cache_txn *txn, knot_pkt_t *pkt, const knot_dname_t
 
 	/* Mark as expiring if it has less than 1% TTL (or less than 5s) */
 	if (is_expiring(&cache_rr, drift)) {
-		if (qry->flags & QUERY_NO_EXPIRING) {
-			return kr_error(ENOENT);
-		} else {
-			qry->flags |= QUERY_EXPIRING;
-		}
+		qry->flags |= QUERY_EXPIRING;
 	}
 
 	/* Update packet question */
@@ -108,7 +104,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt)
 	struct kr_request *req = ctx->data;
 	struct kr_rplan *rplan = &req->rplan;
 	struct kr_query *qry = kr_rplan_current(rplan);
-	if (!qry || ctx->state & (KNOT_STATE_FAIL|KNOT_STATE_DONE)) {
+	if (ctx->state & (KNOT_STATE_FAIL|KNOT_STATE_DONE) || (qry->flags & QUERY_NO_CACHE)) {
 		return ctx->state; /* Already resolved/failed */
 	}
 	if (qry->ns.addr.ip.sa_family != AF_UNSPEC) {
diff --git a/lib/rplan.h b/lib/rplan.h
index cf165768f735d6f92194dfdc4cfaf8fe263bd002..b6ff573d360e81319e82cc9cc3cf370cac7b658f 100644
--- a/lib/rplan.h
+++ b/lib/rplan.h
@@ -36,8 +36,8 @@
 	X(AWAIT_CUT  , 1 << 6) /**< Query is waiting for zone cut lookup */ \
 	X(SAFEMODE   , 1 << 7) /**< Don't use fancy stuff (EDNS...) */ \
 	X(CACHED     , 1 << 8) /**< Query response is cached. */ \
-	X(EXPIRING   , 1 << 9) /**< Query response is cached, but expiring. */ \
-	X(NO_EXPIRING, 1 << 10) /**< Do not use expiring cached records. */ \
+	X(NO_CACHE   , 1 << 9) /**< Do not use expiring cache for lookup. */ \
+	X(EXPIRING   , 1 << 10) /**< Query response is cached, but expiring. */ \
 	X(ALLOW_LOCAL, 1 << 11) /**< Allow queries to local or private address ranges. */ \
 	X(DNSSEC_WANT , 1 << 12) /**< Want DNSSEC secured answer. */ \
 	X(DNSSEC_BOGUS , 1 << 13) /**< Query response is DNSSEC bogus. */ \
diff --git a/modules/predict/predict.lua b/modules/predict/predict.lua
index bc80d11c8b9a77a0f97846beb1c1828a4feb6d35..d462e0ac28b76fb5675e106280fdf56da9cce491 100644
--- a/modules/predict/predict.lua
+++ b/modules/predict/predict.lua
@@ -30,7 +30,7 @@ end
 function predict.drain(ev)
 	local deleted = 0
 	for key, val in pairs(predict.queue) do
-		worker.resolve(string.sub(key, 2), string.byte(key), 1, kres.query.NO_EXPIRING)
+		worker.resolve(string.sub(key, 2), string.byte(key), 1, kres.query.NO_CACHE)
 		predict.queue[key] = nil
 		deleted = deleted + 1
 		if deleted >= predict.batch then