{"record":{"id":"20cbb03bfb2dd153","repo":"AdguardTeam/AdGuardHome","slug":"creating-new-dns-server-config-w","errorCode":null,"errorMessage":"creating new dns server config: %w","messagePattern":"creating new dns server config: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/home/dns.go","lineNumber":176,"sourceCode":"\t\t}\n\t}()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating new dns server: %w\", err)\n\t}\n\n\tglobalContext.clients.clientChecker = globalContext.dnsServer\n\n\tdnsConf, err := newServerConfig(\n\t\t&config.DNS,\n\t\tconfig.Clients.Sources,\n\t\tconfig.HTTPConfig.DoH,\n\t\tparams.TLSManager,\n\t\thttpReg,\n\t\tglobalContext.clients.storage,\n\t\tconfModifier,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating new dns server config: %w\", err)\n\t}\n\n\t// Try to prepare the server with disabled private RDNS resolution if it\n\t// failed to prepare as is.  See TODO on [dnsforward.PrivateRDNSError].\n\terr = globalContext.dnsServer.Prepare(ctx, dnsConf)\n\tif _, ok := errors.AsType[*dnsforward.PrivateRDNSError](err); ok {\n\t\tl := params.Logger\n\t\tl.WarnContext(ctx, \"private rdns resolution failed; disabling\", slogutil.KeyError, err)\n\n\t\tdnsConf.UsePrivateRDNS = false\n\t\terr = globalContext.dnsServer.Prepare(ctx, dnsConf)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"preparing dns server: %w\", err)\n\t}\n\n\treturn nil\n}","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/home/dns.go#L158-L194","documentation":"newServerConfig assembles the dnsforward.ServerConfig (listen addrs, TLS config, upstreams, clients container). It fails when the DNS configuration cannot be translated into a valid server config — most commonly invalid upstream DNS URLs or malformed blocking/clients settings.","triggerScenarios":"Calling newServerConfig with config.DNS containing invalid upstream URLs (e.g. missing scheme, bad tls:// hostname), invalid bootstrap DNS, or TLS manager unable to supply certificates for the configured hostnames.","commonSituations":"Hand-edited config.yaml with typo'd upstream servers, upstreams using DNS-over-TLS/DNS-over-HTTPS with unparseable URLs, or certificate files missing after a migration.","solutions":["Validate every entry in dns.upstream_dns and dns.bootstrap_dns — schemes like tls://, https:// must include valid hostnames","Check tls:// entries have valid server names and that enabled_tls certificates exist","Simplify: temporarily reduce config to one known-good plain upstream (e.g. https://dns.cloudflare.com/dns-query) and re-add entries","Re-run setup from a backup config if the file was hand-edited"],"exampleFix":"# before\nupstream_dns:\n  - tls://1.1.1.1\n# after (DoT requires the server name for TLS validation; use a hostname or dns:// fallback)\nupstream_dns:\n  - tls://one.one.one.one\n  - https://dns.cloudflare.com/dns-query","handlingStrategy":"validation","validationCode":"// validate upstream URLs before building server config\nimport \"net/url\"\nfor _, u := range config.DNS.UpstreamDNS {\n    parsed, err := url.Parse(u)\n    if err != nil || parsed.Host == \"\" {\n        return fmt.Errorf(\"invalid upstream %q\", u)\n    }\n    switch parsed.Scheme {\n    case \"dns\", \"tcp\", \"tls\", \"https\", \"quic\":\n    default:\n        return fmt.Errorf(\"unsupported upstream scheme %q\", u)\n    }\n}","typeGuard":"func isValidUpstream(u string) bool {\n    p, err := url.Parse(u)\n    if err != nil || p.Host == \"\" { return false }\n    switch p.Scheme {\n    case \"dns\", \"tcp\", \"tls\", \"https\", \"quic\": return true\n    }\n    return false\n}","tryCatchPattern":"if _, err := newServerConfig(tlsManager, dnsConf, clients, hosts, modifier); err != nil {\n    return fmt.Errorf(\"creating new dns server config: %w\", err) // inspect wrapped upstream error\n}","preventionTips":["Manage upstream lists via the web UI rather than hand-editing YAML","Add new upstreams one at a time and reload, so a single bad entry is easy to spot","Pin a known-good fallback upstream in every environment"],"tags":["dns","adguard-home","upstream-config","configuration","tls"],"backgroundTag":"config-validation-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}