{"record":{"id":"359f2c4c880c0e6d","repo":"TechnitiumSoftware/DnsServer","slug":"the-query-access-option-is-invalid-for-0-zones","errorCode":null,"errorMessage":"The Query Access option is invalid for {0} zones: {1}","messagePattern":"The Query Access option is invalid for (.+?) zones: (.+?)","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/ForwarderZone.cs","lineNumber":309,"sourceCode":"                base.Disabled = value; //set value early to be able to use it for notify\n\n                if (value)\n                    DisableNotifyTimer();\n                else\n                    TriggerNotify();\n            }\n        }\n\n        public override AuthZoneQueryAccess QueryAccess\n        {\n            get { return base.QueryAccess; }\n            set\n            {\n                switch (value)\n                {\n                    case AuthZoneQueryAccess.AllowOnlyZoneNameServers:\n                    case AuthZoneQueryAccess.AllowZoneNameServersAndUseSpecifiedNetworkACL:\n                        throw new ArgumentException(\"The Query Access option is invalid for \" + GetZoneTypeName() + \" zones: \" + value.ToString(), nameof(QueryAccess));\n                }\n\n                base.QueryAccess = value;\n            }\n        }\n\n        public override AuthZoneTransfer ZoneTransfer\n        {\n            get { return base.ZoneTransfer; }\n            set\n            {\n                switch (value)\n                {\n                    case AuthZoneTransfer.AllowOnlyZoneNameServers:\n                    case AuthZoneTransfer.AllowZoneNameServersAndUseSpecifiedNetworkACL:\n                        throw new ArgumentException(\"The Zone Transfer option is invalid for \" + GetZoneTypeName() + \" zones: \" + value.ToString(), nameof(ZoneTransfer));\n                }\n","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/ForwarderZone.cs#L291-L327","documentation":"Thrown by the ForwarderZone.QueryAccess property setter when value is AuthZoneQueryAccess.AllowOnlyZoneNameServers (3) or AllowZoneNameServersAndUseSpecifiedNetworkACL (5). These two modes restrict queries to the zone's configured authoritative name servers (NS records), but a Conditional Forwarder zone is non-authoritative and carries no NS list — only a dummy SOA and a FWD record — so name-server-based ACLs are meaningless for it. Valid options for a forwarder zone are Deny(0), Allow(1), AllowOnlyPrivateNetworks(2), and UseSpecifiedNetworkACL(4). ArgumentException names the property 'QueryAccess'.","triggerScenarios":"Assigning zone.QueryAccess = AuthZoneQueryAccess.AllowOnlyZoneNameServers (or ...AndUseSpecifiedNetworkACL) on a ForwarderZone, typically via the zone-settings HTTP API or a config import that copied query-access from a primary zone.","commonSituations":"Cloning zone settings from a Primary/Secondary zone into a forwarder zone during bulk config; UI that shows all six options for every zone type without filtering; importing a JSON config that does not model zone-type-specific option sets.","solutions":["For a ForwarderZone use only Deny, Allow, AllowOnlyPrivateNetworks, or UseSpecifiedNetworkACL for QueryAccess.","Filter the offered enum values by zone type in your UI/API before assignment.","If you need NS-based query restriction, use a primary or stub zone instead of a conditional forwarder."],"exampleFix":"// before\nzone.QueryAccess = AuthZoneQueryAccess.AllowOnlyZoneNameServers;\n\n// after\nzone.QueryAccess = AuthZoneQueryAccess.UseSpecifiedNetworkACL; // valid for forwarder","handlingStrategy":"type-guard","validationCode":"var valid = new[] { AuthZoneQueryAccess.Deny, AuthZoneQueryAccess.Allow, AuthZoneQueryAccess.AllowOnlyPrivateNetworks, AuthZoneQueryAccess.UseSpecifiedNetworkACL };\nif (!valid.Contains(value)) throw new ArgumentException($\"QueryAccess {value} not valid for forwarder zone.\");\nzone.QueryAccess = value;","typeGuard":"static bool IsValidForwarderQueryAccess(AuthZoneQueryAccess v) => v == AuthZoneQueryAccess.Deny || v == AuthZoneQueryAccess.Allow || v == AuthZoneQueryAccess.AllowOnlyPrivateNetworks || v == AuthZoneQueryAccess.UseSpecifiedNetworkACL;","tryCatchPattern":"try { zone.QueryAccess = value; }\ncatch (ArgumentException) { /* value was name-server based; fall back to UseSpecifiedNetworkACL */ zone.QueryAccess = AuthZoneQueryAccess.UseSpecifiedNetworkACL; }","preventionTips":["Drive the QueryAccess dropdown from the zone type so name-server modes never appear for forwarders.","Validate config imports per zone type before assignment.","Remember only modes 0,1,2,4 are valid for Conditional Forwarder zones."],"tags":["dns","forwarder-zone","query-access","argumentexception","acl"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}