AdguardTeam/AdGuardHome · error

dnscrypt_config_file: %w

Error message

dnscrypt_config_file: %w

What it means

DNSCrypt is enabled (PortDNSCrypt is non-zero) but no DNSCryptConfigFile was supplied, so the resolver certificate cannot be loaded. The code explicitly returns errors.ErrEmptyValue wrapped with 'dnscrypt_config_file'.

Source

Thrown at internal/home/dns.go:375

	if extTLSConf.PortDNSOverQUIC != 0 {
		dnsConf.QUICListenAddrs = ipsToUDPAddrs(addrs, extTLSConf.PortDNSOverQUIC)
	}

	return dnsConf, nil
}

// newDNSCryptConfig converts values from the configuration file into the
// internal DNSCrypt settings for the DNS server.  extTLSConf must not be nil.
func newDNSCryptConfig(
	extTLSConf *aghtls.ExtendedTLSConfig,
	addrs []netip.Addr,
) (dnsCryptConf *dnsforward.DNSCryptConfig, err error) {
	if extTLSConf.PortDNSCrypt == 0 {
		return nil, nil
	}

	if extTLSConf.DNSCryptConfigFile == "" {
		return nil, fmt.Errorf("dnscrypt_config_file: %w", errors.ErrEmptyValue)
	}

	f, err := os.Open(extTLSConf.DNSCryptConfigFile)
	if err != nil {
		return nil, fmt.Errorf("opening dnscrypt config: %w", err)
	}
	defer func() { err = errors.WithDeferred(err, f.Close()) }()

	rc := &dnscrypt.ResolverConfig{}
	err = yaml.NewDecoder(f).Decode(rc)
	if err != nil {
		return nil, fmt.Errorf("decoding dnscrypt config: %w", err)
	}

	cert, err := rc.NewCert()
	if err != nil {
		return nil, fmt.Errorf("creating dnscrypt cert: %w", err)
	}

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Set dnscrypt_config_file in the tls config section to a valid path, or
  2. Remove/clear the dnscrypt port (set to 0) if DNSCrypt is not wanted
  3. If enabling DNSCrypt, generate a config with dnscrypt generate-cert or copy the sample and reference it

Example fix

# before
tls:
  port_dnscrypt: 5443
  # dnscrypt_config_file missing
# after
tls:
  port_dnscrypt: 5443
  dnscrypt_config_file: /opt/AdGuardHome/dnscrypt-config.yaml
Defensive patterns

Strategy: validation

Validate before calling

// before enabling DNSCrypt
if tlsConf.PortDNSCrypt != 0 && tlsConf.DNSCryptConfigFile == "" {
    return fmt.Errorf("dnscrypt port set but dnscrypt_config_file is empty")
}

Type guard

func dnscryptConfigComplete(t *TLSConfig) bool {
    return t.PortDNSCrypt == 0 || t.DNSCryptConfigFile != ""
}

Try / catch

if err != nil { // from newDNSCryptConfig
    if errors.Is(err, errors.ErrEmptyValue) {
        // set dnscrypt_config_file or clear port_dnscrypt, then retry init
    }
}

Prevention

When it happens

Trigger: Setting the dnscrypt listening port in the TLS/DNS config while leaving the dnscrypt_config_file path empty — newDNSCryptConfig short-circuits with ErrEmptyValue.

Common situations: Hand-editing config.yaml to add a DNSCrypt port without adding the config file path, or a setup wizard/migration dropping the field.

Related errors


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