{"record":{"id":"039d63a0f3dbd59c","repo":"AdguardTeam/AdGuardHome","slug":"creating-dns-server-w","errorCode":null,"errorMessage":"creating dns server: %w","messagePattern":"creating dns server: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/home/dns.go","lineNumber":131,"sourceCode":"\t\tDNSFilter:   globalContext.filters,\n\t\tStats:       globalContext.stats,\n\t\tQueryLog:    globalContext.queryLog,\n\t\tPrivateNets: parseSubnetSet(config.DNS.PrivateNets),\n\t\tAnonymizer:  anonymizer,\n\t\tDHCPServer:  globalContext.dhcpServer,\n\t\tEtcHosts:    hc,\n\t\tLocalDomain: config.DHCP.LocalDomainName,\n\t\tTLSManager:  tlsManager,\n\t}\n\n\terr = initDNSServer(\n\t\tctx,\n\t\tparams,\n\t\thttpReg,\n\t\tconfModifier,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating dns server: %w\", err)\n\t}\n\n\tfor _, route := range config.HTTPConfig.DoH.Routes {\n\t\tmux.Handle(route, globalContext.dnsServer)\n\t}\n\n\treturn nil\n}\n\n// initDNSServer initializes the [context.dnsServer].  To only use the internal\n// proxy, none of the arguments are required, but params must be non-nil and\n// valid.  In other cases all the arguments also must not be nil.  It also must\n// not be called unless [config] and [globalContext] are\n// initialized.\nfunc initDNSServer(\n\tctx context.Context,\n\tparams dnsforward.DNSCreateParams,\n\thttpReg aghhttp.Registrar,","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/home/dns.go#L113-L149","documentation":"AdGuard Home could not create its DNS server instance (dnsforward.Server created via dnsServerNew with the TLS manager, HTTP registrar, and clients storage). Creation fails when the supplied parameters are invalid, e.g. bad TLS material registration or listener/socket problems on the requested addresses.","triggerScenarios":"Calling initDNS when dnsServerNew fails: invalid listening addresses, port already in use, failure wiring the HTTP/Doh registrar or TLS manager into the dnsforward server constructor.","commonSituations":"Port 53 (or DoH/DoT/DoQ ports) already bound by systemd-resolved or another DNS server; invalid listen interface IPs in config; insufficient privileges to bind low ports.","solutions":["Check the wrapped error for the exact cause (bind: address already in use is typical)","Free the conflicting port (e.g. disable systemd-resolved stub listener or stop the other DNS server)","Verify listening interface IPs in config.yaml still exist on the host","Run with CAP_NET_BIND_SERVICE or as root when binding ports <1024"],"exampleFix":"# before\n# port 53 occupied by systemd-resolved\n# after\nsudo mkdir -p /etc/systemd/resolved.conf.d\necho -e '[Resolve]\nDNSStubListener=no' | sudo tee /etc/systemd/resolved.conf.d/adguard.conf\nsudo systemctl restart systemd-resolved","handlingStrategy":"validation","validationCode":"// pre-flight: ensure DNS ports are free\nimport \"net\"\nfunc portFree(network string, port int) bool {\n    l, err := net.Listen(network, fmt.Sprintf(\":%d\", port))\n    if err != nil { return false }\n    l.Close()\n    return true\n}\n// refuse to start if 53/853/443 conflict\nfor _, p := range []struct{n string; v int}{{\"udp\",53},{\"tcp\",53}} {\n    if !portFree(p.n, p.v) { return fmt.Errorf(\"port %d/%s busy\", p.v, p.n) }\n}","typeGuard":null,"tryCatchPattern":"if err := initDNS(ctx, params); err != nil {\n    var se *net.OpError\n    if errors.As(err, &se) && se.Op == \"listen\" {\n        log.Error(\"DNS port conflict — stop competing resolver\", slogutil.KeyError, err)\n    }\n    return fmt.Errorf(\"creating dns server: %w\", err)\n}","preventionTips":["Disable systemd-resolved DNSStubListener on Linux before installing","Reserve DNS/DoH/DoT ports exclusively for AdGuard Home in deployment configs","Use systemd unit with CAP_NET_BIND_SERVICE instead of root"],"tags":["dns","adguard-home","server-startup","port-binding","network"],"backgroundTag":"address-already-in-use","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}