The forward plugin forwards DNS queries to upstream resolvers. It supports multiple upstreams, load-balancing strategies, failover, optional health checks, and DNS-over-HTTPS (DoH).
round_robin, random, fastestmax_attemptsconcurrent)addr|tag syntaxconcurrent mode is enabled (legacy numeric concurrent > 1), the plugin races queries to all upstreams and uses the first successful response.max_attempts.https://dns.example/dns-query).udp:// or tcp://; the plugin will accept either and normalize addresses to include a port (default port 53 if missing).The plugin accepts an args map with the following keys:
upstreams (required): an array of upstreams. Each entry can be either a string or a mapping.
8.8.8.8:53udp://8.8.8.8:53 (prefix optional)https://dns.example/dns-query (DoH)8.8.8.8:53|primary (append |tag to provide a human tag){ addr: "1.1.1.1:53", tag: "cloudflare" }timeout: integer seconds for per-query timeout (default: 5)strategy: one of round_robin (default), random, or fastesthealth_checks: boolean to enable health tracking (default: false)max_attempts: integer controlling maximum failover attempts (default: 3)concurrent: integer (legacy); values > 1 enable racing concurrent queriesBasic forwarder with two UDP upstreams:
plugins:
- tag: forward
type: forward
args:
upstreams:
- "8.8.8.8:53"
- "1.1.1.1:53|cloudflare"
timeout: 5
strategy: round_robin
health_checks: true
max_attempts: 3
Using DoH and fastest strategy:
plugins:
- tag: forward_secure
type: forward
args:
upstreams:
- "https://doh.example/dns-query"
- "https://doh2.example/dns-query|doh2"
strategy: fastest
timeout: 3
health_checks: true
Concurrent (race) mode (legacy concurrent > 1):
plugins:
- tag: forward_race
type: forward
args:
upstreams:
- "8.8.8.8:53"
- "1.1.1.1:53"
concurrent: 2
health_checks is enabled the plugin updates per-upstream counters and (if metrics feature compiled) exposes Prometheus metrics:
UPSTREAM_QUERIES_TOTAL (labels: upstream, status)UPSTREAM_DURATION_SECONDS (labels: upstream)Look for log fields like upstream, elapsed_ms, queries, successes, and failures when debugging upstream behavior.
LAZYDNS_DOH_ACCEPT_INVALID_CERT in test contexts.timeout for slow networks or remote resolvers.max_attempts.strategy: fastest to prefer faster upstreams automatically once response times have been measured.addr|tag) to label upstreams for easier log/metric identification.fastest strategy when you have reliable latency metrics and mixed upstreams (DoH vs UDP).health_checks if you want the plugin to track upstream performance and failures and to drive more informed failover.