diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
index 35a5740c91..3fdf5de58b 100644
--- a/man/resolved.conf.xml
+++ b/man/resolved.conf.xml
@@ -251,8 +251,16 @@
request. Be aware that turning off caching comes at a performance penalty, which is particularly high
when DNSSEC is used. If no-negative, only positive answers are cached.
- Note that caching is turned off implicitly if the configured DNS server is on a host-local IP address
- (such as 127.0.0.1 or ::1), in order to avoid duplicate local caching.
+ Note that caching is turned off by default for host-local DNS servers.
+ See CacheFromLocalhost= for details.
+
+
+
+ CacheFromLocalhost=
+ Takes a boolean as argument. If no (the default), and response cames from
+ host-local IP address (such as 127.0.0.1 or ::1), the result wouldn't be cached in order to avoid
+ potential duplicate local caching.
+
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 7d6ee2bc4c..0c804d6d2b 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -221,14 +221,6 @@ void dns_packet_rewind(DnsPacket *p, size_t idx);
int dns_packet_skip_question(DnsPacket *p);
int dns_packet_extract(DnsPacket *p);
-static inline bool DNS_PACKET_SHALL_CACHE(DnsPacket *p) {
- /* Never cache data originating from localhost, under the
- * assumption, that it's coming from a locally DNS forwarder
- * or server, that is caching on its own. */
-
- return in_addr_is_localhost(p->family, &p->sender) == 0;
-}
-
/* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 */
enum {
DNS_RCODE_SUCCESS = 0,
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 1b8bead7c3..7a2d8723a0 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -682,11 +682,9 @@ static void dns_transaction_cache_answer(DnsTransaction *t) {
if (t->scope->manager->enable_cache == DNS_CACHE_MODE_NO)
return;
- /* We never cache if this packet is from the local host, under
- * the assumption that a locally running DNS server would
- * cache this anyway, and probably knows better when to flush
- * the cache then we could. */
- if (!DNS_PACKET_SHALL_CACHE(t->received))
+ /* Packet from localhost? */
+ if (!t->scope->manager->cache_from_localhost &&
+ in_addr_is_localhost(t->received->family, &t->received->sender) != 0)
return;
dns_cache_put(&t->scope->cache,
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index 88b0d8eab9..7f0b8e7847 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -2,6 +2,7 @@
#pragma once
#include "sd-event.h"
+#include "in-addr-util.h"
typedef struct DnsTransaction DnsTransaction;
typedef enum DnsTransactionState DnsTransactionState;
diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf
index b54fa1ba99..2da273ab1e 100644
--- a/src/resolve/resolved-gperf.gperf
+++ b/src/resolve/resolved-gperf.gperf
@@ -30,3 +30,4 @@ Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0,
Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
Resolve.ResolveUnicastSingleLabel, config_parse_bool, 0, offsetof(Manager, resolve_unicast_single_label)
Resolve.DNSStubListenerExtra, config_parse_dns_stub_listener_extra, 0, offsetof(Manager, dns_extra_stub_listeners)
+Resolve.CacheFromLocalhost, config_parse_bool, 0, offsetof(Manager, cache_from_localhost)
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
index 20afab05fd..739683cbb5 100644
--- a/src/resolve/resolved-manager.h
+++ b/src/resolve/resolved-manager.h
@@ -39,6 +39,7 @@ struct Manager {
DnssecMode dnssec_mode;
DnsOverTlsMode dns_over_tls_mode;
DnsCacheMode enable_cache;
+ bool cache_from_localhost;
DnsStubListenerMode dns_stub_listener_mode;
#if ENABLE_DNS_OVER_TLS
diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in
index 93279b3dff..e1d06c0fb1 100644
--- a/src/resolve/resolved.conf.in
+++ b/src/resolve/resolved.conf.in
@@ -24,6 +24,7 @@
#MulticastDNS=@DEFAULT_MDNS_MODE@
#LLMNR=@DEFAULT_LLMNR_MODE@
#Cache=yes
+#CacheFromLocalhost=no
#DNSStubListener=yes
#DNSStubListenerExtra=
#ReadEtcHosts=yes
diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
index 30ce98687a..464496e257 100644
--- a/test/fuzz/fuzz-unit-file/directives.service
+++ b/test/fuzz/fuzz-unit-file/directives.service
@@ -374,6 +374,7 @@ Bond=
Bridge=
Broadcast=
Cache=
+CacheFromLocalhost=
ClientIdentifier=
ConfigureWithoutCarrier=
CopyDSCP=