{"record":{"id":"b3c07768f788eeb3","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-transfer-configuration-only-the-primary","errorCode":null,"errorMessage":"Failed to transfer configuration: only the Primary node can transfer the configuration.","messagePattern":"Failed to transfer configuration: only the Primary node can transfer the configuration\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":878,"sourceCode":"            SaveConfigFile();\n\n            //notify all secondary nodes\n            TriggerNotifyAllSecondaryNodes();\n\n            //trigger NS and SOA update for member zones only if secondary node domain name has changed\n            if (secondaryNodeDomainChanged)\n                TriggerRecordUpdateForClusterCatalogMemberZones();\n\n            return secondaryNode;\n        }\n\n        public Task TransferConfigAsync(Stream zipStream, DateTime ifModifiedSince, ICollection<string> includeZones)\n        {\n            if (!ClusterInitialized)\n                throw new DnsServerException(\"Failed to transfer configuration: the Cluster is not initialized.\");\n\n            if (GetSelfNode().Type != ClusterNodeType.Primary)\n                throw new DnsServerException(\"Failed to transfer configuration: only the Primary node can transfer the configuration.\");\n\n            return _dnsWebService.BackupConfigAsync(zipStream: zipStream,\n                                                    authConfig: true,\n                                                    clusterConfig: false,\n                                                    webServiceSettings: false,\n                                                    dnsSettings: true,\n                                                    logSettings: false,\n                                                    zones: true,\n                                                    allowedZones: true,\n                                                    blockedZones: true,\n                                                    blockLists: true,\n                                                    apps: true,\n                                                    scopes: false,\n                                                    stats: false,\n                                                    logs: false,\n                                                    isConfigTransfer: true,\n                                                    ifModifiedSince: ifModifiedSince,\n                                                    includeZones: includeZones);","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L860-L896","documentation":"TransferConfigAsync is restricted to the cluster Primary (GetSelfNode().Type == Primary). Only the Primary owns the authoritative configuration to push to Secondaries.","triggerScenarios":"A Secondary node serving a config-transfer request; an L4 load balancer routing the pull to a non-Primary member; a role change after the client pinned the endpoint.","commonSituations":"Failover changing the Primary; client targeting a member IP instead of the Primary role; a misconfigured Secondary 'primary URL'.","solutions":["Pull configuration from the current Primary only","Re-resolve which node is Primary before each transfer","Fix the Secondary's configured Primary URL"],"exampleFix":"// before\nawait clusterManager.TransferConfigAsync(stream, since, zones);\n\n// after\nif (clusterManager.GetSelfNode().Type != ClusterNodeType.Primary)\n    return Redirect(\"Config transfer is served by the Primary node.\");\nawait clusterManager.TransferConfigAsync(stream, since, zones);","handlingStrategy":"validation","validationCode":"if (clusterManager.GetSelfNode().Type != ClusterNodeType.Primary)\n    return BadRequest(\"Only the Primary serves config transfer.\");\nreturn await clusterManager.TransferConfigAsync(stream, ifModifiedSince, includeZones);","typeGuard":null,"tryCatchPattern":"catch (DnsServerException ex) when (ex.Message.Contains(\"only the Primary node can transfer\"))\n{ /* rediscover Primary and retry */ }","preventionTips":["Secondaries must resolve the Primary role, not a fixed IP","Re-validate the Primary endpoint after any failover"],"tags":["cluster","primary-node","config-transfer","authorization","dns-server"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}