AdguardTeam/AdGuardHome · error

preparing dns server: %w

Error message

preparing dns server: %w

What it means

dnsforward.Server.Prepare validates the prepared ServerConfig and gets the server ready to listen; this error means the final Prepare call failed even after the automatic retry with private reverse-DNS resolution disabled. Typical causes are invalid upstream configuration or listener address problems surfaced at prepare time.

Source

Thrown at internal/home/dns.go:190

		globalContext.clients.storage,
		confModifier,
	)
	if err != nil {
		return fmt.Errorf("creating new dns server config: %w", err)
	}

	// Try to prepare the server with disabled private RDNS resolution if it
	// failed to prepare as is.  See TODO on [dnsforward.PrivateRDNSError].
	err = globalContext.dnsServer.Prepare(ctx, dnsConf)
	if _, ok := errors.AsType[*dnsforward.PrivateRDNSError](err); ok {
		l := params.Logger
		l.WarnContext(ctx, "private rdns resolution failed; disabling", slogutil.KeyError, err)

		dnsConf.UsePrivateRDNS = false
		err = globalContext.dnsServer.Prepare(ctx, dnsConf)
	}
	if err != nil {
		return fmt.Errorf("preparing dns server: %w", err)
	}

	return nil
}

// parseSubnetSet parses a slice of subnets.  If the slice is empty, it returns
// a subnet set that matches all locally served networks, see
// [netutil.IsLocallyServed].
func parseSubnetSet(nets []netutil.Prefix) (s netutil.SubnetSet) {
	switch len(nets) {
	case 0:
		// Use an optimized function-based matcher.
		return netutil.SubnetSetFunc(netutil.IsLocallyServed)
	case 1:
		return nets[0].Prefix
	default:
		return netutil.SliceSubnetSet(netutil.UnembedPrefixes(nets))
	}

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Check the wrapped error: upstream errors usually name the exact server URL that failed
  2. Fix or remove failing upstreams from config.yaml dns section and reload
  3. If the error mentions private RDNS, disable 'Use private reverse DNS resolvers' in settings
  4. Verify listen addresses/interfaces and free any occupied DNS ports

Example fix

# before
dns:
  enable_reverse_mapping: true
  private_reverse_dns_servers:
    - 192.168.1.1
# after — drop unreachable private resolvers or disable reverse mapping
dns:
  enable_reverse_mapping: false
Defensive patterns

Strategy: fallback

Validate before calling

// probe upstreams before Prepare
func upstreamAlive(addr string) bool {
    r := net.Resolver{}
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()
    _, err := r.LookupHost(ctx, "example.com")
    _ = addr
    return err == nil
}

Try / catch

err = dnsServer.Prepare(ctx, dnsConf)
if _, ok := errors.AsType[*dnsforward.PrivateRDNSError](err); ok {
    dnsConf.UsePrivateRDNS = false
    err = dnsServer.Prepare(ctx, dnsConf) // built-in fallback already retries once
}
if err != nil { return fmt.Errorf("preparing dns server: %w", err) }

Prevention

When it happens

Trigger: Calling dnsServer.Prepare(ctx, dnsConf) failing twice: once as-is, once with UsePrivateRDNS=false (the retry only happens when the error is a *dnsforward.PrivateRDNSError). Underlying failures include unreachable/invalid upstream servers and bind-address problems.

Common situations: Upstream DNS servers unreachable or misconfigured (bad DoH/DoT URLs), private-RDNS enabled in an environment lacking reverse resolvers, or listen addresses that cannot be prepared on this host.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/ad72666cd1c0d6f2. Report an issue: GitHub.