{"record":{"id":"1e20ea031a758fce","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-resync-configuration-only-secondary-nod","errorCode":null,"errorMessage":"Failed to resync configuration: only Secondary nodes can sync configuration from Primary nodes.","messagePattern":"Failed to resync configuration: only Secondary nodes can sync configuration from Primary nodes\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"warning","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1627,"sourceCode":"\n            ClusterNode primaryNode = GetPrimaryNode();\n\n            if (primaryNode.State == ClusterNodeState.Self)\n                throw new DnsServerException(\"Failed to refresh configuration: only Secondary nodes can sync configuration from Primary nodes.\");\n\n            TriggerRefreshForConfig(CONFIG_REFRESH_TIMER_INTERVAL, configRefreshIncludeZones);\n        }\n\n        public void TriggerResyncForConfig()\n        {\n            //do validation\n            if (!ClusterInitialized)\n                throw new DnsServerException(\"Failed to resync configuration: the Cluster is not initialized.\");\n\n            ClusterNode primaryNode = GetPrimaryNode();\n\n            if (primaryNode.State == ClusterNodeState.Self)\n                throw new DnsServerException(\"Failed to resync configuration: only Secondary nodes can sync configuration from Primary nodes.\");\n\n            _configLastSynced = DateTime.UnixEpoch; //to ensure complete config resync\n\n            //trigger immediate config refresh\n            TriggerRefreshForConfig(0);\n        }\n\n        private void TriggerRefreshForConfig(int refreshInterval, IReadOnlyCollection<string> configRefreshIncludeZones = null)\n        {\n            _configRefreshLock.Wait();\n            try\n            {\n                if (configRefreshIncludeZones is not null)\n                {\n                    if (_configRefreshIncludeZones is null)\n                        _configRefreshIncludeZones = configRefreshIncludeZones;\n                    else\n                        _configRefreshIncludeZones = [.. _configRefreshIncludeZones, .. configRefreshIncludeZones];","sourceCodeStart":1609,"sourceCodeEnd":1645,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1609-L1645","documentation":"Thrown by TriggerResyncForConfig when GetPrimaryNode().State == ClusterNodeState.Self: this server is the primary. Like the refresh variant (192), resync pulls config from an upstream primary, which a primary node does not have. The guard stops the primary from attempting to resync from itself.","triggerScenarios":"Calling TriggerResyncForConfig on the primary node of the cluster.","commonSituations":"Logged into the primary when clicking 'resync config from primary'; automation runs the resync job on all cluster members including the primary.","solutions":["Call TriggerResyncForConfig only from Secondary nodes.","Branch shared automation on GetPrimaryNode().State and skip resync on the primary.","Disable the resync action in the UI when the current node is the primary."],"exampleFix":"// before\nclusterManager.TriggerResyncForConfig();\n\n// after\nif (clusterManager.GetPrimaryNode().State == ClusterNodeState.Self)\n    return Ok(\"Primary node; nothing to resync.\");\nclusterManager.TriggerResyncForConfig();","handlingStrategy":"validation","validationCode":"if (clusterManager.GetPrimaryNode().State == ClusterNodeState.Self)\n    return Ok(\"Primary node; nothing to resync.\");\nclusterManager.TriggerResyncForConfig();","typeGuard":"static bool CanResyncFromPrimary(ClusterManager cm)\n    => cm.ClusterInitialized && cm.GetPrimaryNode().State != ClusterNodeState.Self;","tryCatchPattern":"try { clusterManager.TriggerResyncForConfig(); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"only Secondary nodes can sync\"))\n{ /* primary node; no-op */ }","preventionTips":["Call resync only from secondaries.","Branch automation on node role to skip resync on the primary.","Resync is heavyweight (full pull) — confirm the node is a secondary first."],"tags":["cluster","role-guard","config-resync","primary-node","technitium"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}