{"record":{"id":"4335f244f53f1a76","repo":"TechnitiumSoftware/DnsServer","slug":"groups-array-was-not-defined","errorCode":null,"errorMessage":"Groups array was not defined.","messagePattern":"Groups array was not defined\\.","errorType":"exception","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"Apps/AdvancedForwardingApp/App.cs","lineNumber":167,"sourceCode":"                return new Tuple<NetworkAddress, string>(networkAddress, jsonGroup.ToString());\n            });\n\n            if (jsonConfig.TryReadArrayAsMap(\"groups\", ReadGroup, out Dictionary<string, Group>? groups) && (groups is not null))\n            {\n                if (_groups is not null)\n                {\n                    foreach (KeyValuePair<string, Group> group in _groups)\n                    {\n                        if (!groups.ContainsKey(group.Key))\n                            group.Value.Dispose();\n                    }\n                }\n\n                _groups = groups;\n            }\n            else\n            {\n                throw new FormatException(\"Groups array was not defined.\");\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public Task<DnsDatagram?> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed)\n        {\n            if (!_enableForwarding || !request.RecursionDesired)\n                return Task.FromResult<DnsDatagram?>(null);\n\n            IPAddress remoteIP = remoteEP.Address;\n            NetworkAddress? network = null;\n            string? groupName = null;\n\n            foreach (KeyValuePair<NetworkAddress, string> entry in _networkGroupMap!)\n            {\n                if (entry.Key.Contains(remoteIP) && ((network is null) || (entry.Key.PrefixLength > network.PrefixLength)))\n                {","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/Apps/AdvancedForwardingApp/App.cs#L149-L185","documentation":"Thrown by the AdvancedForwardingApp initializer when the 'groups' property is absent or is not a JSON array. TryReadArrayAsMap returns false in that case, and since groups are mandatory the app throws FormatException and refuses to load.","triggerScenarios":"Calling the AdvancedForwardingApp initializer with a config that omits the 'groups' array entirely, sets it to null, or provides an object/scalar instead of an array.","commonSituations":"Starting from a minimal config template that only defined 'forwarders'; deleting the groups block during manual editing; config corruption; upgrading from an older config schema that lacked groups.","solutions":["Add a 'groups' array to dnsApp.config with at least one group object (each group needs at least a name).","Confirm 'groups' is a JSON array (square brackets), not an object.","Regenerate the app config from the web UI or copy from the app's example/default config."],"exampleFix":"// before (dnsApp.config)\n{ \"enableForwarding\": true }\n// after\n{ \"enableForwarding\": true, \"groups\": [ { \"name\": \"default\", \"forwarders\": [] } ] }","handlingStrategy":"validation","validationCode":"if (!jsonConfig.TryGetProperty(\"groups\", out JsonElement g) || g.ValueKind != JsonValueKind.Array || g.GetArrayLength() == 0)\n    throw new FormatException(\"AdvancedForwardingApp requires a non-empty 'groups' JSON array.\");","typeGuard":"static bool HasValidGroups(JsonElement c) => c.TryGetProperty(\"groups\", out JsonElement g) && g.ValueKind == JsonValueKind.Array && g.GetArrayLength() > 0;","tryCatchPattern":null,"preventionTips":["Always include a 'groups' array with at least one group in the AdvancedForwardingApp config.","Start from the app's default/example config template.","Use the web UI to generate the config to avoid missing required keys."],"tags":["csharp","config","json","schema","technitium","advanced-forwarding-app"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}