{"record":{"id":"ef655391c719b8c9","repo":"TechnitiumSoftware/DnsServer","slug":"invalid-adguard-upstreams-config-file-format-miss-ef6553","errorCode":null,"errorMessage":"Invalid AdGuard Upstreams config file format: missing default upstream servers.","messagePattern":"Invalid AdGuard Upstreams config file format: missing default upstream servers\\.","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"Apps/AdvancedForwardingApp/App.cs","lineNumber":655,"sourceCode":"                            if (line.Length == 0)\n                                continue; //skip empty line\n\n                            if (line.StartsWith('#'))\n                                continue; //skip comment line\n\n                            if (line.StartsWith('['))\n                            {\n                                int i = line.LastIndexOf(']');\n                                if (i < 0)\n                                    throw new FormatException(\"Invalid AdGuard Upstreams config file format: missing ']' bracket.\");\n\n                                string[] domains = line.Substring(1, i - 1).Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);\n                                string forwarder = line.Substring(i + 1);\n\n                                if (forwarder == \"#\")\n                                {\n                                    if (defaultForwarderRecords.Count == 0)\n                                        throw new FormatException(\"Invalid AdGuard Upstreams config file format: missing default upstream servers.\");\n\n                                    forwardings.Add(new Forwarding(defaultForwarderRecords, domains));\n                                }\n                                else\n                                {\n                                    List<DnsForwarderRecordData> forwarderRecords = new List<DnsForwarderRecordData>();\n                                    string word = PopWord(ref forwarder);\n\n                                    while (word.Length > 0)\n                                    {\n                                        string nextWord = PopWord(ref forwarder);\n\n                                        if (nextWord.StartsWith('('))\n                                        {\n                                            word += \" \" + nextWord;\n                                            nextWord = PopWord(ref forwarder);\n                                        }\n","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/Apps/AdvancedForwardingApp/App.cs#L637-L673","documentation":"Thrown while parsing an AdGuard Upstreams file when a domain-scoped line uses '#' as its upstream (the AdGuard convention meaning 'use the default upstream'), but no default upstream servers were defined earlier in the file. The defaultForwarderRecords list is empty, so FormatException is raised.","triggerScenarios":"An AdGuard upstreams file where the first domain-specific line is '[/example.com/] #' (use default) but no plain upstream lines (the default servers) appeared before it. Default servers are the non-'[' lines at the top of the file.","commonSituations":"Deleting the top default-server lines of an AdGuard upstreams file while keeping '#' references; pasting only the domain-specific rules; file truncated at the top.","solutions":["Add at least one default upstream server line at the top of the AdGuard upstreams file before any '[/.../] #' line (e.g. 'https://dns.google/dns-query').","Reorder so all default (non-bracketed) upstream lines come before domain-specific '#' rules.","If you do not want a shared default, replace '#' with an explicit upstream server on that line."],"exampleFix":"// before (upstreams file)\n[/example.com/] #\n// after\nhttps://dns.google/dns-query\n[/example.com/] #","handlingStrategy":"validation","validationCode":"// Ensure at least one default (non-'[') upstream line precedes any '#'-default rule.\nvar lines = File.ReadAllLines(upstreamsPath).Where(l => { var t = l.TrimStart(); return t.Length > 0 && !t.StartsWith('#'); });\nbool hasDefault = lines.Any(l => !l.TrimStart().StartsWith('['));\nbool usesHashDefault = lines.Any(l => l.TrimStart().StartsWith('[') && l.Substring(l.LastIndexOf(']') + 1).Trim() == \"#\");\nif (usesHashDefault && !hasDefault) throw new FormatException(\"AdGuard upstreams uses '#' default but defines no default upstream line.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Place default upstream server lines at the top of the AdGuard file.","Avoid '#' default references until at least one default server is declared.","Re-download upstream files from a verified source."],"tags":["csharp","config","adguard","format","technitium","advanced-forwarding-app"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}