{"record":{"id":"f95013e4935074aa","repo":"TechnitiumSoftware/DnsServer","slug":"forwarder-was-not-defined-forwardername","errorCode":null,"errorMessage":"Forwarder was not defined: {forwarderName}","messagePattern":"Forwarder was not defined: (.+?)","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"Apps/AdvancedForwardingApp/App.cs","lineNumber":374,"sourceCode":"\n            IReadOnlyList<DnsForwarderRecordData> _forwarderRecords;\n            readonly HashSet<string> _domains;\n\n            #endregion\n\n            #region constructor\n\n            public Forwarding(JsonElement jsonForwarding, Dictionary<string, ConfigForwarder>? configForwarders)\n            {\n                JsonElement jsonForwarders = jsonForwarding.GetProperty(\"forwarders\");\n                List<DnsForwarderRecordData> forwarderRecords = new List<DnsForwarderRecordData>();\n\n                foreach (JsonElement jsonForwarder in jsonForwarders.EnumerateArray())\n                {\n                    string forwarderName = jsonForwarder.ToString();\n\n                    if ((configForwarders is null) || !configForwarders.TryGetValue(forwarderName, out ConfigForwarder? configForwarder))\n                        throw new FormatException(\"Forwarder was not defined: \" + forwarderName);\n\n                    forwarderRecords.AddRange(configForwarder.ForwarderRecords);\n                }\n\n                _forwarderRecords = forwarderRecords;\n\n                _domains = jsonForwarding.ReadArrayAsSet(\"domains\") ?? [];\n            }\n\n            public Forwarding(IReadOnlyList<string> domains, NameServerAddress forwarder, bool dnssecValidation, ConfigProxyServer proxy)\n                : this([GetForwarderRecord(forwarder, dnssecValidation, proxy)], domains)\n            { }\n\n            public Forwarding(IReadOnlyList<DnsForwarderRecordData> forwarderRecords, IReadOnlyList<string> domains)\n            {\n                _forwarderRecords = forwarderRecords;\n\n                _domains = new HashSet<string>(domains.Count);","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/Apps/AdvancedForwardingApp/App.cs#L356-L392","documentation":"Thrown while building an AdvancedForwardingApp Forwarding rule from the 'forwarders' array inside a forwarding definition. Each entry is a forwarder name that must exist in the top-level 'forwarders' map; if configForwarders is null or the name is missing, FormatException is raised.","triggerScenarios":"A forwarding rule references a forwarder name (string element of the rule's 'forwarders' array) that was never declared in the top-level 'forwarders' configuration object, or the 'forwarders' block itself was omitted so the map is null.","commonSituations":"Renaming a forwarder in the 'forwarders' block but forgetting to update references inside groups; a typo in the forwarder name; deleting the 'forwarders' block while keeping rules that use it.","solutions":["Cross-check each name in the forwarding rule's 'forwarders' array against the keys of the top-level 'forwarders' object in dnsApp.config and fix typos.","If the top-level 'forwarders' block is missing, add it and define the referenced forwarder(s).","Keep forwarder names consistent when renaming by updating all referencing rules at the same time."],"exampleFix":"// before (dnsApp.config)\n\"forwarders\": { \"google\": { ... } },\n\"groups\": [ { \"forwarders\": [ { \"forwarders\": [ \"googl\" ] } ] } ]\n// after\n\"groups\": [ { \"forwarders\": [ { \"forwarders\": [ \"google\" ] } ] } ]","handlingStrategy":"validation","validationCode":"HashSet<string> declared = configForwarders?.Keys.ToHashSet() ?? new HashSet<string>();\nforeach (string name in ruleForwarderNames)\n{\n    if (!declared.Contains(name))\n        throw new FormatException($\"Forwarding rule references undefined forwarder '{name}'. Known: {string.Join(\", \", declared)}.\");\n}","typeGuard":"static bool IsForwarderDefined(string name, Dictionary<string, ConfigForwarder>? map) => map is not null && map.ContainsKey(name);","tryCatchPattern":null,"preventionTips":["Define forwarders in the top-level 'forwarders' block before referencing them in rules.","When renaming a forwarder, update all referencing rules together.","Run a config reference check before applying."],"tags":["csharp","config","json","schema","reference","technitium","advanced-forwarding-app"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}