{"record":{"id":"7b245cc7b5f01010","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-update-dns-zone-zoneinfo-displayname-n","errorCode":null,"errorMessage":"Cannot update DNS zone '{zoneInfo.DisplayName}': not a primary or a forwarder zone.","messagePattern":"Cannot update DNS zone '(.+?)': not a primary or a forwarder zone\\.","errorType":"exception","errorClass":"DhcpServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dhcp/DhcpServer.cs","lineNumber":803,"sourceCode":"                    zoneInfo = _dnsServer.AuthZoneManager.CreatePrimaryZone(scope.DomainName);\n                    if (zoneInfo is null)\n                    {\n                        _log.Write(\"DHCP Server failed to create DNS primary zone '\" + scope.DomainName + \"'.\");\n                        return;\n                    }\n\n                    //set permissions\n                    _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n                    _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n                    _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.DHCP_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n                    _authManager.SaveConfigFile();\n\n                    _log.Write(\"DHCP Server create DNS primary zone '\" + zoneInfo.DisplayName + \"'.\");\n                }\n                else if ((zoneInfo.Type != AuthZoneType.Primary) && (zoneInfo.Type != AuthZoneType.Forwarder))\n                {\n                    if (zoneInfo.Name.Equals(scope.DomainName, StringComparison.OrdinalIgnoreCase))\n                        throw new DhcpServerException(\"Cannot update DNS zone '\" + zoneInfo.DisplayName + \"': not a primary or a forwarder zone.\");\n\n                    //create new primary zone\n                    zoneInfo = _dnsServer.AuthZoneManager.CreatePrimaryZone(scope.DomainName);\n                    if (zoneInfo is null)\n                    {\n                        _log.Write(\"DHCP Server failed to create DNS primary zone '\" + scope.DomainName + \"'.\");\n                        return;\n                    }\n\n                    //set permissions\n                    _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n                    _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n                    _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.DHCP_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n                    _authManager.SaveConfigFile();\n\n                    _log.Write(\"DHCP Server create DNS primary zone '\" + zoneInfo.DisplayName + \"'.\");\n                }\n","sourceCodeStart":785,"sourceCodeEnd":821,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dhcp/DhcpServer.cs#L785-L821","documentation":"Thrown by DhcpServer when it tries to update DNS records for a DHCP scope but the existing DNS zone matching scope.DomainName has a type other than Primary or Forwarder (e.g. Secondary, Stub, Cache). Only Primary/Forwarder zones can be dynamically written by DHCP, so updating a read-only zone is refused. The guard only fires when the conflicting zone name exactly equals the scope's domain name.","triggerScenarios":"Activating/enabling a DHCP scope whose DomainName equals an existing AuthZone with zoneInfo.Type not in {Primary, Forwarder}. Concretely the check `(zoneInfo.Type != AuthZoneType.Primary) && (zoneInfo.Type != AuthZoneType.Forwarder)` AND `zoneInfo.Name.Equals(scope.DomainName, OrdinalIgnoreCase)` both hold.","commonSituations":"Admin manually created a Secondary or Stub zone for the same domain the DHCP scope serves. Zone type changed after scope creation. Split-horizon / conditional-forwarder setups that produced a non-Primary zone with the scope's domain.","solutions":["In the DNS UI/API, convert the existing zone matching scope.DomainName to type Primary or Forwarder, then re-enable the scope.","Delete or rename the conflicting Secondary/Stub zone so DHCP can create its own primary zone.","Change the scope's DomainName to a sub-domain for which no non-Primary zone exists."],"exampleFix":"// before: scope.DomainName == 'corp.local' but a Secondary zone 'corp.local' exists\n// after: change zone type to Primary (or remove it) before enabling the scope\n_dnsServer.AuthZoneManager.SetZoneType('corp.local', AuthZoneType.Primary);\n_dhcpServer.EnableScope('corp');","handlingStrategy":"validation","validationCode":"var zone = _dnsServer.AuthZoneManager.GetZone(scope.DomainName);\nif (zone != null && zone.Type != AuthZoneType.Primary && zone.Type != AuthZoneType.Forwarder)\n    throw new InvalidOperationException($\"Zone '{scope.DomainName}' is {zone.Type}; convert to Primary/Forwarder before enabling DHCP scope.\");","typeGuard":"static bool ZoneIsWritable(AuthZoneInfo z) => z != null && (z.Type == AuthZoneType.Primary || z.Type == AuthZoneType.Forwarder);","tryCatchPattern":"try { _dhcpServer.EnableScope(scope.Name); }\ncatch (DhcpServerException ex) when (ex.Message.Contains(\"not a primary or a forwarder zone\"))\n{ /* convert zone type, then retry once */ }","preventionTips":["Keep forward zones for DHCP-served domains as Primary or Forwarder.","Before enabling a scope, assert the matching zone is writable.","Document which domains are DHCP-managed to avoid creating Secondary zones over them."],"tags":["dhcp","dns","zone-type","configuration"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}