{"record":{"id":"9a2d99d02d01e65f","repo":"TechnitiumSoftware/DnsServer","slug":"local-end-point-group-map-contains-an-invalid-end","errorCode":null,"errorMessage":"Local end point group map contains an invalid end point: {localEP}","messagePattern":"Local end point group map contains an invalid end point: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Apps/AdvancedBlockingApp/App.cs","lineNumber":370,"sourceCode":"                throw new InvalidOperationException();\n\n            Directory.CreateDirectory(Path.Combine(_dnsServer.ApplicationFolder, \"blocklists\"));\n            using JsonDocument jsonDocument = JsonDocument.Parse(config, _jsonParseOptions);\n            JsonElement jsonConfig = jsonDocument.RootElement;\n\n            _enableBlocking = jsonConfig.GetPropertyValue(\"enableBlocking\", true);\n            _blockingAnswerTtl = jsonConfig.GetPropertyValue(\"blockingAnswerTtl\", 30u);\n            _blockListUrlUpdateIntervalHours = jsonConfig.GetPropertyValue(\"blockListUrlUpdateIntervalHours\", 24);\n            _blockListUrlUpdateIntervalMinutes = jsonConfig.GetPropertyValue(\"blockListUrlUpdateIntervalMinutes\", 0);\n\n            _soaRecord = new DnsSOARecordData(_dnsServer.ServerDomain, _dnsServer.ResponsiblePerson.Address, 1, 14400, 3600, 604800, _blockingAnswerTtl);\n            _nsRecord = new DnsNSRecordData(_dnsServer.ServerDomain);\n\n            if (jsonConfig.TryReadObjectAsMap(\"localEndPointGroupMap\",\n                delegate (string localEP, JsonElement jsonGroup)\n                {\n                    if (!EndPointExtensions.TryParse(localEP, out EndPoint ep))\n                        throw new InvalidOperationException(\"Local end point group map contains an invalid end point: \" + localEP);\n\n                    return new Tuple<EndPoint, string>(ep, jsonGroup.GetString() ?? \"\");\n                },\n                out Dictionary<EndPoint, string>? localEndPointGroupMap))\n            {\n                _localEndPointGroupMap = localEndPointGroupMap;\n            }\n\n            _networkGroupMap = jsonConfig.ReadObjectAsMap(\"networkGroupMap\", delegate (string network, JsonElement jsonGroup)\n            {\n                if (!NetworkAddress.TryParse(network, out NetworkAddress networkAddress))\n                    throw new InvalidOperationException(\"Network group map contains an invalid network address: \" + network);\n\n                return new Tuple<NetworkAddress, string>(networkAddress, jsonGroup.GetString() ?? \"\");\n            });\n\n            {\n                Dictionary<Uri, BlockList> allAllowListZones = new Dictionary<Uri, BlockList>(0);","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/Apps/AdvancedBlockingApp/App.cs#L352-L388","documentation":"Thrown while parsing the AdvancedBlockingApp 'localEndPointGroupMap' JSON object in the app config. Each map key is passed to EndPointExtensions.TryParse (expects an IP:port endpoint like '192.168.1.5:53'); when parsing fails the key is rejected as invalid. The error is an InvalidOperationException raised during app initialization, so the app fails to load the config.","triggerScenarios":"Calling the AdvancedBlockingApp initializer with a 'localEndPointGroupMap' whose key string is not a parseable endpoint (e.g. a bare IP without a port, a hostname, '0.0.0.0', or a malformed address like '999.1.1.1:53'). EndPointExtensions.TryParse returns false for that key.","commonSituations":"Copying a subnet value from 'networkGroupMap' into 'localEndPointGroupMap' (CIDR notation like '10.0.0.0/24' is rejected because endpoints require a port); forgetting the ':53' port; pasting a hostname instead of an IP.","solutions":["Open dnsApp.config and fix the offending 'localEndPointGroupMap' key so it is a valid IP endpoint with a port (e.g. change '192.168.1.10' to '192.168.1.10:53').","Verify the key matches the client's local source endpoint as the server observes it; for IPv6 use bracketed form like '[fe80::1]:53'.","If you intended a subnet-based group, move that entry into 'networkGroupMap' instead, which accepts CIDR notation."],"exampleFix":"// before (dnsApp.config)\n\"localEndPointGroupMap\": { \"192.168.1.10\": \"groupA\" }\n// after\n\"localEndPointGroupMap\": { \"192.168.1.10:53\": \"groupA\" }","handlingStrategy":"validation","validationCode":"// Validate every 'localEndPointGroupMap' key is a parseable endpoint before applying config.\nforeach (string key in localEndPointGroupMapKeys)\n{\n    if (!EndPointExtensions.TryParse(key, out EndPoint _))\n        throw new FormatException($\"'localEndPointGroupMap' key '{key}' is not a valid IP:port endpoint. Expected e.g. '192.168.1.10:53'.\");\n}","typeGuard":"static bool IsValidLocalEndPointKey(string key) => EndPointExtensions.TryParse(key, out EndPoint _);","tryCatchPattern":null,"preventionTips":["Always include the ':port' (typically ':53') on localEndPointGroupMap keys.","Keep CIDR subnets in networkGroupMap, never in localEndPointGroupMap.","Validate the JSON config with a schema/linter before deploying."],"tags":["csharp","config","json","endpoint","technitium","advanced-blocking-app"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}